": {
"service_name": "Fiverr",
"price": "0.20",
"procent_days": "30",
"procent": "30",
"day_step": "0.00",
"country": "KZ",
"phoneAmount": 79
}
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | |
| **`data.*`** | object | |
| **`data.*.service_name`** | string | |
| **`data.*.price`** | string | |
| **`data.*.procent_days`** | string | |
| **`data.*.procent`** | string | |
| **`data.*.day_step`** | string | |
| **`data.*.country`** | string | |
| **`data.*.phoneAmount`** | integer | |
| **`msg`** | string | Error message when status is 0. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Rental countries (/en/docs/rental/countries)
GET{"https://smspva.com/api/rent.php?method=getcountries"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
You can call this method without an API key.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "getcountries" | Method name |
## How to use this method [#how-to-use-this-method]
Find the countries currently available for number rental. Use a returned code with [Rental data](/en/docs/rental/data) or [Data by provider](/en/docs/rental/data-by-provider) to check services, prices and stock.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getcountries"
```
```js
const query = new URLSearchParams({
"method": "getcountries"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const query = new URLSearchParams({
"method": "getcountries"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
query = {
"method": "getcountries"
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getcountries'
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
query := url.Values{}
query.Set("method", "getcountries")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var query = new Dictionary {
["method"] = "getcountries"
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
Map query = new LinkedHashMap<>();
query.put("method", "getcountries");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": [
{
"name": "United States",
"code": "US",
"url_country_name": "united-states",
"rent_switch_type": "FAST",
"rent_avail_prolong": "1"
}
]
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | |
| **`data`** | array<object> | |
| **`data[].name`** | string | Country name |
| **`data[].code`** | string | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`data[].url_country_name`** | string | Country slug used in public URLs. |
| **`data[].rent_switch_type`** | string | Rental availability mode for the country. |
| **`data[].rent_avail_prolong`** | string | Indicates whether rental prolongation is available for the country. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Counts by provider (/en/docs/rental/counts-by-provider)
GET{"https://smspva.com/api/rent.php?method=getCountWithProviders"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
The **apikey** query parameter is optional. Omit it for public data; set it for account-specific data or pricing where documented.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "getCountWithProviders" | Method name |
| **`apikey`** | query | string | No | (optional) | Optional API key. When supplied, it may affect personalized rental data. |
| **`country`** | query | string | Yes | "KZ" | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`dtype`** | query | string | No | "week" | Type of period: week or month Defaults to week when omitted. |
| **`dcount`** | query | integer | No | 1 | Count type of period, i.e. if **`dtype`**=week then counts of weeks Defaults to 1 when omitted. |
## How to use this method [#how-to-use-this-method]
Compare stock by service and provider. For each service code, **`Amount`** maps provider names to counts and **`Total`** gives the combined number. Read these keys from the response: both service codes and provider names can change.
Check JSON **`status`** even with HTTP **200**. If it is **0**, read the error in **`msg`**.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
# Optional: add --data-urlencode "apikey=$SMSPVA_API_KEY" for account-specific data.
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getCountWithProviders" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getCountWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getCountWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ.get("SMSPVA_API_KEY")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getCountWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getCountWithProviders',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := os.Getenv("SMSPVA_API_KEY")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getCountWithProviders")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getCountWithProviders",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", "");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getCountWithProviders");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": {
"opt48": {
"Amount": {
"Limbo_AT": 12,
"Tele2_AT": 1,
"yesss_AT": 69
},
"Total": 82
}
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | Service codes mapped to provider counts and totals. |
| **`data.*`** | object | |
| **`data.*.Amount`** | object | Provider names mapped to available number counts. |
| **`data.*.Amount.*`** | integer | |
| **`data.*.Total`** | integer | Total available numbers for the service. |
| **`msg`** | string | Error message when status is 0. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Create multi-service rental (/en/docs/rental/create-multi)
GET{"https://smspva.com/api/rent.php?method=create_multi"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
This request can modify a rental or incur charges. If the response is lost, check your orders and history before trying again: the change may already have been made. The examples do not retry automatically.
## Authentication [#authentication]
Send **apikey** as a required **query parameter**.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "create_multi" | Method name |
| **`apikey`** | query | string | Yes | **`SMSPVA_API_KEY`** | Your API key You can find it on the website in the top right drop-down menu in the Profile and APIKEY section |
| **`dtype`** | query | string | Yes | "week" | Type of period: week or month |
| **`dcount`** | query | integer | Yes | 1 | Count type of period, i.e. if **`dtype`**=week then counts of weeks |
| **`country`** | query | string | Yes | "KZ" | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`services`** | query | string | Yes | "opt6,opt7,opt8" | Services codes separated by commas [Services list](/en/docs/rental/reference-data) |
| **`provider`** | query | string | No | "T-Mobile" | Optional parameter. Provider name. If not specified, a provider will be chosen randomly from the available ones. |
| **`partner_key`** | query | string | No | "partnerkeyhere" | Optional partner key for referral accounting. |
## How to use this method [#how-to-use-this-method]
Rent one number for several services. Pass their comma-separated codes in **`services`** and first check [Multi-service count](/en/docs/rental/multi-service-count).
Choose a [country](/en/docs/rental/countries) and compare [services, providers and prices](/en/docs/rental/data-by-provider) for the same country and duration. After creating the rental, find it in [Rental orders](/en/docs/rental/orders) and [activate it](/en/docs/rental/activate) before sending an SMS.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=create_multi" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1" \
--data-urlencode "country=KZ" \
--data-urlencode "services=opt6,opt7,opt8"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt6,opt7,opt8";
const query = new URLSearchParams({
"method": "create_multi",
"dtype": dtype,
"dcount": dcount,
"country": country,
"services": services
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt6,opt7,opt8";
const query = new URLSearchParams({
"method": "create_multi",
"dtype": dtype,
"dcount": dcount,
"country": country,
"services": services
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
services = os.environ.get("SMSPVA_RENTAL_SERVICES", "opt6,opt7,opt8")
query = {
"method": "create_multi",
"dtype": dtype,
"dcount": dcount,
"country": country,
"services": services
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'create_multi',
'dtype' => $dtype,
'dcount' => $dcount,
'country' => $country,
'services' => $services
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
services := env("SMSPVA_RENTAL_SERVICES", "opt6,opt7,opt8")
query := url.Values{}
query.Set("method", "create_multi")
query.Set("dtype", dtype)
query.Set("dcount", dcount)
query.Set("country", country)
query.Set("services", services)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var services = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICES") ?? "opt6,opt7,opt8";
var query = new Dictionary {
["method"] = "create_multi",
["dtype"] = dtype,
["dcount"] = dcount,
["country"] = country,
["services"] = services
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String services = env("SMSPVA_RENTAL_SERVICES", "opt6,opt7,opt8");
Map query = new LinkedHashMap<>();
query.put("method", "create_multi");
query.put("dtype", dtype);
query.put("dcount", dcount);
query.put("country", country);
query.put("services", services);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": {
"id": 40370,
"pnumber": "9096037108",
"ccode": "+7",
"service": "opt6",
"until": "1587633960"
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | |
| **`data.id`** | integer | ID of order |
| **`data.pnumber`** | string | Phone number without country code |
| **`data.ccode`** | string | Digital country code |
| **`data.service`** | string | Service code [Services list](/en/docs/rental/reference-data) |
| **`data.until`** | string | UNIX timestamp of expire date |
| **`msg`** | string | Error message when status is 0. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Create rental (/en/docs/rental/create)
GET{"https://smspva.com/api/rent.php?method=create"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
This request can modify a rental or incur charges. If the response is lost, check your orders and history before trying again: the change may already have been made. The examples do not retry automatically.
## Authentication [#authentication]
Send **apikey** as a required **query parameter**.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "create" | Method name |
| **`apikey`** | query | string | Yes | **`SMSPVA_API_KEY`** | Your API key You can find it on the website in the top right drop-down menu in the Profile and APIKEY section |
| **`dtype`** | query | string | Yes | "week" | Type of period: week or month |
| **`dcount`** | query | integer | Yes | 1 | Count type of period, i.e. if **`dtype`**=week then counts of weeks |
| **`country`** | query | string | Yes | "KZ" | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`service`** | query | string | Yes | "opt6" | Service code [Services list](/en/docs/rental/reference-data) |
| **`provider`** | query | string | No | "T-Mobile" | Optional parameter. Provider name. If not specified, a provider will be chosen randomly from the available ones. |
| **`partner_key`** | query | string | No | "partnerkeyhere" | Optional partner key for referral accounting. |
## How to use this method [#how-to-use-this-method]
Rent a number for one service. For several services on the same number, use [Create multi-service rental](/en/docs/rental/create-multi) after checking [availability](/en/docs/rental/multi-service-count).
Choose a [country](/en/docs/rental/countries) and compare [services, providers and prices](/en/docs/rental/data-by-provider) for the same country and duration. After creating the rental, find it in [Rental orders](/en/docs/rental/orders) and [activate it](/en/docs/rental/activate) before sending an SMS.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=create" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1" \
--data-urlencode "country=KZ" \
--data-urlencode "service=opt6"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt6";
const query = new URLSearchParams({
"method": "create",
"dtype": dtype,
"dcount": dcount,
"country": country,
"service": service
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt6";
const query = new URLSearchParams({
"method": "create",
"dtype": dtype,
"dcount": dcount,
"country": country,
"service": service
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
service = os.environ.get("SMSPVA_RENTAL_SERVICE", "opt6")
query = {
"method": "create",
"dtype": dtype,
"dcount": dcount,
"country": country,
"service": service
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'create',
'dtype' => $dtype,
'dcount' => $dcount,
'country' => $country,
'service' => $service
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
service := env("SMSPVA_RENTAL_SERVICE", "opt6")
query := url.Values{}
query.Set("method", "create")
query.Set("dtype", dtype)
query.Set("dcount", dcount)
query.Set("country", country)
query.Set("service", service)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var service = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICE") ?? "opt6";
var query = new Dictionary {
["method"] = "create",
["dtype"] = dtype,
["dcount"] = dcount,
["country"] = country,
["service"] = service
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String service = env("SMSPVA_RENTAL_SERVICE", "opt6");
Map query = new LinkedHashMap<>();
query.put("method", "create");
query.put("dtype", dtype);
query.put("dcount", dcount);
query.put("country", country);
query.put("service", service);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": {
"id": 40370,
"pnumber": "9096037108",
"ccode": "+7",
"service": "opt6",
"until": "1587633960"
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | |
| **`data.id`** | integer | ID of order |
| **`data.pnumber`** | string | Phone number without country code |
| **`data.ccode`** | string | Digital country code |
| **`data.service`** | string | Service code [Services list](/en/docs/rental/reference-data) |
| **`data.until`** | string | UNIX timestamp of expire date |
| **`msg`** | string | Error message when status is 0. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Rental data by provider (/en/docs/rental/data-by-provider)
GET{"https://smspva.com/api/rent.php?method=getdataWithProviders"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
The **apikey** query parameter is optional. Omit it for public data; set it for account-specific data or pricing where documented.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "getdataWithProviders" | Method name |
| **`apikey`** | query | string | No | (optional) | Optional API key. When supplied, it may affect personalized rental data and prices. |
| **`country`** | query | string | Yes | "KZ" | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`dtype`** | query | string | No | "week" | Type of period: week or month Defaults to week when omitted. |
| **`dcount`** | query | integer | No | 1 | Count type of period, i.e. if **`dtype`**=week then counts of weeks Defaults to 1 when omitted. |
| **`extend`** | query | string | No | "1" | Optional flag enabling extended response format. |
## How to use this method [#how-to-use-this-method]
Compare the services available in a **`country`**, their daily prices and the providers supplying them. Use the same **`dtype`** and **`dcount`** that you plan to rent.
Choose a country from [Rental countries](/en/docs/rental/countries), then pass your service code to [Create rental](/en/docs/rental/create) or [Create multi-service rental](/en/docs/rental/create-multi).
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
# Optional: add --data-urlencode "apikey=$SMSPVA_API_KEY" for account-specific data.
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getdataWithProviders" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdataWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdataWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ.get("SMSPVA_API_KEY")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getdataWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getdataWithProviders',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := os.Getenv("SMSPVA_API_KEY")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getdataWithProviders")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getdataWithProviders",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", "");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getdataWithProviders");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": {
"services": [
{
"name": "1cupis & okcupid & winline",
"service": "opt48",
"price_day": 5,
"img": "images/ico/cupis_okcupid_winline.ico",
"procent_days": 0,
"procent": 0,
"day_step": 0,
"count": {
"Claro_AR": 27
},
"totalCount": 12
}
],
"totalAmount": 1735,
"allOperators": [
"Claro_AR"
]
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | |
| **`data.services`** | array<object> | |
| **`data.services[].name`** | string | Service name |
| **`data.services[].service`** | string | Service code [Services list](/en/docs/rental/reference-data) |
| **`data.services[].price_day`** | number | Price per day for this service |
| **`data.services[].img`** | string | Service icon URL |
| **`data.services[].procent_days`** | integer | Number of days for discount |
| **`data.services[].procent`** | integer | Discount percentage |
| **`data.services[].day_step`** | integer | Day step for pricing |
| **`data.services[].count`** | object | Number of available numbers for this service from each operator |
| **`data.services[].count.*`** | integer | |
| **`data.services[].totalCount`** | integer | Total count of available numbers for this service |
| **`data.totalAmount`** | integer | Total count of available numbers for all services |
| **`data.allOperators`** | array<string> | List of all available operators in this country |
| **`msg`** | string | Error message when status is 0. The API may return HTTP 200 for this result. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Rental data (/en/docs/rental/data)
GET{"https://smspva.com/api/rent.php?method=getdata"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
The **apikey** query parameter is optional. Omit it for public data; set it for account-specific data or pricing where documented.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "getdata" | Method name |
| **`apikey`** | query | string | No | (optional) | Optional API key. When supplied, it may affect personalized rental data. |
| **`country`** | query | string | Yes | "KZ" | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`dtype`** | query | string | No | "week" | Type of period: week or month Defaults to week when omitted. |
| **`dcount`** | query | integer | No | 1 | Count type of period, i.e. if **`dtype`**=week then counts of weeks Defaults to 1 when omitted. |
| **`extend`** | query | string | No | "1" | Set to 1 to include **`procent_days`**, procent and **`day_step`** pricing settings in each service entry. |
## How to use this method [#how-to-use-this-method]
Look up service prices and available numbers for your **`country`** and rental duration. Set **`dtype`** to **`week`** or **`month`**, and **`dcount`** to the number of periods.
Service entries include names, codes, daily prices, counts and icon paths; **`data.totalAmount`** gives the total. Add **`extend=1`** to include the pricing settings **`procent_days`**, **`procent`** and **`day_step`**. Check JSON **`status`**: **0** means the request failed, with details in **`msg`**, even if HTTP is **200**.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
# Optional: add --data-urlencode "apikey=$SMSPVA_API_KEY" for account-specific data.
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getdata" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdata",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdata",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ.get("SMSPVA_API_KEY")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getdata",
"country": country,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getdata',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := os.Getenv("SMSPVA_API_KEY")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getdata")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getdata",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", "");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getdata");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": {
"services": [
{
"name": "Airbnb",
"service": "opt46",
"price_day": 6,
"count": 359,
"img": "images/ico/whatsapp.png",
"procent_days": 0,
"procent": 0,
"day_step": 0
}
],
"totalAmount": 100
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | |
| **`data.services`** | array<object> | |
| **`data.services[].name`** | string | Service name |
| **`data.services[].service`** | string | Service code [Services list](/en/docs/rental/reference-data) |
| **`data.services[].price_day`** | number | Price per day |
| **`data.services[].count`** | integer | Available count |
| **`data.services[].img`** | string | Service icon path. |
| **`data.services[].procent_days`** | integer | Number of days for discount Returned with **`extend=1`**. |
| **`data.services[].procent`** | integer | Discount percentage Returned with **`extend=1`**. |
| **`data.services[].day_step`** | number | Day step for pricing Returned with **`extend=1`**. |
| **`data.totalAmount`** | integer | Total count of available numbers for all services |
| **`msg`** | string | Error message when status is 0. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Default services (/en/docs/rental/default-services)
GET{"https://smspva.com/api/rent.php?method=get_default_services"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
You can call this method without an API key.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "get_default_services" | Method name |
## How to use this method [#how-to-use-this-method]
Get the rental API’s default service list. For prices and available numbers in a particular country, use [Rental data](/en/docs/rental/data) or [Data by provider](/en/docs/rental/data-by-provider).
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_default_services"
```
```js
const query = new URLSearchParams({
"method": "get_default_services"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const query = new URLSearchParams({
"method": "get_default_services"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
query = {
"method": "get_default_services"
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_default_services'
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
query := url.Values{}
query.Set("method", "get_default_services")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var query = new Dictionary {
["method"] = "get_default_services"
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
Map query = new LinkedHashMap<>();
query.put("method", "get_default_services");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": [
{
"name": "WhatsApp",
"service": "opt20",
"priceForDay": "0.20",
"img": "images/ico/whatsapp.png",
"DAYP": "30",
"PROC": "30"
}
]
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | array<object> | |
| **`data[].name`** | string | Service name. |
| **`data[].service`** | string | Service code. |
| **`data[].priceForDay`** | string | Daily rental price, returned as a string. |
| **`data[].img`** | string | Service icon path. |
| **`data[].DAYP`** | string | Rental pricing setting returned by the server. |
| **`data[].PROC`** | string | Rental pricing setting returned by the server. |
| **`msg`** | string | Error message when status is 0. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Remove order (/en/docs/rental/delete)
GET{"https://smspva.com/api/rent.php?method=delete"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
This request can modify a rental or incur charges. If the response is lost, check your orders and history before trying again: the change may already have been made. The examples do not retry automatically.
## Authentication [#authentication]
Send **apikey** as a required **query parameter**.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "delete" | Method name |
| **`apikey`** | query | string | Yes | **`SMSPVA_API_KEY`** | Your API key You can find it on the website in the top right drop-down menu in the Profile and APIKEY section |
| **`id`** | query | integer | Yes | "" | ID of order |
## How to use this method [#how-to-use-this-method]
Remove the rental order. Send **GET** with **`method=delete`**; use the order ID required by this method.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=delete" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "delete",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "delete",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "delete",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'delete',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "delete")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "delete",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "delete");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": {
"id": 123
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | |
| **`data.id`** | integer | ID of order |
| **`msg`** | string | Error message when status is 0. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Rental errors and responses (/en/docs/rental/errors)
## HTTP and application status are separate [#http-and-application-status-are-separate]
Rental methods document HTTP **200** responses. A body with **status=0** is still a failure. **status=1** means success. Read **msg** when present; do not require Activation V2 fields such as **`statusCode`** or **`error.type`**.
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
This is an error you can receive from **`restore_user`**. Its method page shows both success and error responses, so check which one you received before reading the restored order ID.
## Waiting and empty message lists [#waiting-and-empty-message-lists]
Activation V2's **202 / SMS_NOT_YET_RECEIVED** handling does not apply to Rental. A successful **sms** response can contain an empty **SmsList** or **OtherSms**. Check order activation state and rental expiry through **orders** when deciding whether to wait.
## Transport failures [#transport-failures]
A timeout, connection failure, empty HTTP body or non-JSON response does not provide a usable success result. Stop the one-shot example and decide how to recover. In particular, the source notes that **get_min_paypal_days** may return an empty body when country or service is missing; supply its required parameters.
If a request to create or change a rental times out, check your orders and history before trying again: it may already have completed. A GET request can also create a paid order, and the examples do not add duplicate-request protection.
## Preserve the source error messages [#preserve-the-source-error-messages]
The Restore Rental examples include **Incorrect order id**, **Order not found**, **NOBALANCE_12.50**, and **The number is busy, there is already an order for this service**. These are examples of messages you may receive; other methods can return different messages.
Use the HTTP method and response codes shown on the [method page](/en/docs/rental).
# Rental code examples (/en/docs/rental/examples)
Every [Rental method](/en/docs/rental) includes cURL, JavaScript, TypeScript, Python, PHP, Go, C# and Java. They send URL-encoded query parameters to **https://smspva.com/api/rent.php** using GET.
## Environments [#environments]
| Language | Requirements |
| --- | --- |
| cURL | cURL 7.76+, POSIX shell on macOS/Linux/WSL |
| JavaScript | Node.js 22.16+; save as Example.mjs |
| TypeScript | Node.js ESM project with Node types; save as Example.mts |
| Python | Python 3.10+, standard library; python Example.py |
| PHP | PHP 8.1+ with ext-curl; php Example.php |
| Go | Go 1.20+, standard library; go run Example.go |
| C# | .NET 8+ console project; put code in Program.cs |
| Java | JDK 11+ and Jackson Databind on the classpath |
Java uses Jackson to check JSON **status** even when HTTP is 200. Add this dependency to your Maven project:
```xml
com.fasterxml.jackson.core
jackson-databind
2.22.4
```
Version source: [Maven Central](https://central.sonatype.com/artifact/com.fasterxml.jackson.core/jackson-databind). Compile Example.java and run Example with the project dependencies on the classpath or through your IDE. The other examples require no third-party HTTP or JSON package.
## API key [#api-key]
Required-key methods read **SMSPVA_API_KEY**. Optional-key methods omit it if unset; public methods do not request a key at all. The key belongs in the query string **apikey**, not in a header.
```text
# macOS / Linux / WSL
export SMSPVA_API_KEY="YOUR_API_KEY"
```
```text
# PowerShell
$env:SMSPVA_API_KEY = "YOUR_API_KEY"
```
Keep credentials in server-side environment variables. Query strings can appear in proxy/access logs; configure redaction of **`apikey`**. Do not expose account requests in public browser code.
## Order and number variables [#order-and-number-variables]
```text
# PowerShell — replace with your rental values
$env:SMSPVA_RENTAL_ORDER_ID = "123"
$env:SMSPVA_RENTAL_NUMBER = "79335445295"
```
Use IDs from Rental orders/history, not Activation V2. Number values follow each method's **pnumber** description.
Other examples use source sample values. Override them in code or through **SMSPVA_RENTAL_COUNTRY**, **SMSPVA_RENTAL_SERVICE**, **SMSPVA_RENTAL_SERVICES**, **SMSPVA_RENTAL_DTYPE**, **SMSPVA_RENTAL_DCOUNT**, **SMSPVA_RENTAL_SKIP**, **SMSPVA_RENTAL_TAKE**, **SMSPVA_RENTAL_RENT_DAYS**, where the method accepts them. The cURL snippets contain literal country/service/duration values to edit directly.
## Optional parameters [#optional-parameters]
Minimal examples omit optional **provider**, **partner_key** and **extend**. Add them only to methods that document them. **partner_key** is a Rental query parameter; it is different from the Activation V2 **`partnerkey`** header. For account-specific prices in methods with optional **`apikey`**, set **`SMSPVA_API_KEY`**; the cURL example explains how to add it.
The examples use a 30-second timeout and no automatic retries. They URL-encode commas, spaces and other query characters. cURL prints the JSON body; check **status** yourself before using **data**. JavaScript/TypeScript, Python, PHP, Go, C# and Java check both HTTP and the Rental JSON status.
# Rental history (/en/docs/rental/history)
GET{"https://smspva.com/api/rent.php?method=get_rent_history"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
Send **apikey** as a required **query parameter**.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "get_rent_history" | Method name |
| **`apikey`** | query | string | Yes | **`SMSPVA_API_KEY`** | Your API key You can find it on the website in the top right drop-down menu in the Profile and APIKEY section |
| **`skip`** | query | integer | No | 0 | Number of items to skip |
| **`take`** | query | integer | No | 10 | Number of items received |
## How to use this method [#how-to-use-this-method]
Find completed rentals and check **`isAvailForRestore`** to see which can be restored. For an eligible order, check [cost and duration](/en/docs/rental/restore-precalculation) before [restoring it](/en/docs/rental/restore).
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_rent_history" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "skip=0" \
--data-urlencode "take=10"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const skip = process.env.SMSPVA_RENTAL_SKIP ?? "0";
const take = process.env.SMSPVA_RENTAL_TAKE ?? "10";
const query = new URLSearchParams({
"method": "get_rent_history",
"skip": skip,
"take": take
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const skip = process.env.SMSPVA_RENTAL_SKIP ?? "0";
const take = process.env.SMSPVA_RENTAL_TAKE ?? "10";
const query = new URLSearchParams({
"method": "get_rent_history",
"skip": skip,
"take": take
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
skip = os.environ.get("SMSPVA_RENTAL_SKIP", "0")
take = os.environ.get("SMSPVA_RENTAL_TAKE", "10")
query = {
"method": "get_rent_history",
"skip": skip,
"take": take
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_rent_history',
'skip' => $skip,
'take' => $take
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
skip := env("SMSPVA_RENTAL_SKIP", "0")
take := env("SMSPVA_RENTAL_TAKE", "10")
query := url.Values{}
query.Set("method", "get_rent_history")
query.Set("skip", skip)
query.Set("take", take)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var skip = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SKIP") ?? "0";
var take = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_TAKE") ?? "10";
var query = new Dictionary {
["method"] = "get_rent_history",
["skip"] = skip,
["take"] = take
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String skip = env("SMSPVA_RENTAL_SKIP", "0");
String take = env("SMSPVA_RENTAL_TAKE", "10");
Map query = new LinkedHashMap<>();
query.put("method", "get_rent_history");
query.put("skip", skip);
query.put("take", take);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": [
{
"orderId": 857191,
"resourceCode": "opt9",
"number": "37067787324",
"branchId": 684,
"haveSms": false,
"isAvailForRestore": true,
"days": 30,
"country": "LT",
"begin": 1768902473,
"end": 1771494473,
"closed": 1768903921
}
]
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | array<object> | |
| **`data[].orderId`** | integer | ID of order |
| **`data[].resourceCode`** | string | Service code [Services list](/en/docs/rental/reference-data) |
| **`data[].number`** | string | rented phone number with country code without plus sign |
| **`data[].branchId`** | integer | Internal branch ID for the order |
| **`data[].haveSms`** | boolean | Whether SMS was received on this number during the rental |
| **`data[].isAvailForRestore`** | boolean | Whether this order can be restored (renewed). If true, you can use the Restore method to renew this rental with a new number. |
| **`data[].days`** | integer | Number of days the order was rented for |
| **`data[].country`** | string | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`data[].begin`** | integer | UNIX timestamp of start date |
| **`data[].end`** | integer | UNIX timestamp of end date |
| **`data[].closed`** | integer | UNIX timestamp of closed date |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Rental API (/en/docs/rental)
Endpoint: **https://smspva.com/api/rent.php**. Every documented method uses **GET**, selected by the **method** query parameter. Rental credentials use an **apikey query parameter**, not the Activation V2 header. Check JSON **status=1** before using data; **status=0** is an application failure even with HTTP 200.
Create, activate, read messages, prolong and restore.
Live rental lists from the existing source.
## Reference data [#reference-data]
| method | Description |
| --- | --- |
| **`getcountries`** | [Rental countries](/en/docs/rental/countries) |
| **`get_default_services`** | [Default services](/en/docs/rental/default-services) |
| **`get_country_by_service`** | [Countries by service](/en/docs/rental/countries-by-service) |
## Prices & availability [#prices--availability]
| method | Description |
| --- | --- |
| **`getdata`** | [Rental data](/en/docs/rental/data) |
| **`getdataWithProviders`** | [Rental data by provider](/en/docs/rental/data-by-provider) |
| **`getcount`** | [Available number counts](/en/docs/rental/count) |
| **`getCountWithProviders`** | [Counts by provider](/en/docs/rental/counts-by-provider) |
| **`get_count_multi`** | [Multi-service count](/en/docs/rental/multi-service-count) |
| **`get_days_canada_paypal`** | [Canada PayPal days](/en/docs/rental/canada-paypal-days) |
| **`get_min_paypal_days`** | [Minimum PayPal days](/en/docs/rental/minimum-paypal-days) |
## Orders & SMS [#orders--sms]
| method | Description |
| --- | --- |
| **`create`** | [Create rental](/en/docs/rental/create) |
| **`create_multi`** | [Create multi-service rental](/en/docs/rental/create-multi) |
| **`add_service_to_order`** | [Add service to order](/en/docs/rental/add-service) |
| **`orders`** | [Rental orders](/en/docs/rental/orders) |
| **`activate`** | [Activate rental](/en/docs/rental/activate) |
| **`sms`** | [Rental SMS](/en/docs/rental/sms) |
## Manage rentals [#manage-rentals]
| method | Description |
| --- | --- |
| **`prolong`** | [Prolong rental](/en/docs/rental/prolong) |
| **`prolong_max`** | [Prolong by days](/en/docs/rental/prolong-max) |
| **`delete`** | [Remove order](/en/docs/rental/delete) |
## History & restoration [#history--restoration]
| method | Description |
| --- | --- |
| **`get_rent_history`** | [Rental history](/en/docs/rental/history) |
| **`restore_user_precalc`** | [Restore precalculation](/en/docs/rental/restore-precalculation) |
| **`restore_user`** | [Restore rental](/en/docs/rental/restore) |
# Minimum PayPal days (/en/docs/rental/minimum-paypal-days)
GET{"https://smspva.com/api/rent.php?method=get_min_paypal_days"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
You can call this method without an API key.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "get_min_paypal_days" | Method name |
| **`country`** | query | string | Yes | "CA" | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`service`** | query | string | Yes | "opt83" | Service code [Services list](/en/docs/rental/reference-data) |
## How to use this method [#how-to-use-this-method]
Check the shortest PayPal rental period for your **`country`** and **`service`**. Send both parameters: the backend may return an empty HTTP body if either is missing. Country codes are in [Rental countries](/en/docs/rental/countries). For Canada, also see [Canada PayPal days](/en/docs/rental/canada-paypal-days).
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_min_paypal_days" \
--data-urlencode "country=CA" \
--data-urlencode "service=opt83"
```
```js
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "CA";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt83";
const query = new URLSearchParams({
"method": "get_min_paypal_days",
"country": country,
"service": service
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "CA";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt83";
const query = new URLSearchParams({
"method": "get_min_paypal_days",
"country": country,
"service": service
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "CA")
service = os.environ.get("SMSPVA_RENTAL_SERVICE", "opt83")
query = {
"method": "get_min_paypal_days",
"country": country,
"service": service
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_min_paypal_days',
'country' => $country,
'service' => $service
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
country := env("SMSPVA_RENTAL_COUNTRY", "CA")
service := env("SMSPVA_RENTAL_SERVICE", "opt83")
query := url.Values{}
query.Set("method", "get_min_paypal_days")
query.Set("country", country)
query.Set("service", service)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "CA";
var service = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICE") ?? "opt83";
var query = new Dictionary {
["method"] = "get_min_paypal_days",
["country"] = country,
["service"] = service
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String country = env("SMSPVA_RENTAL_COUNTRY", "CA");
String service = env("SMSPVA_RENTAL_SERVICE", "opt83");
Map query = new LinkedHashMap<>();
query.put("method", "get_min_paypal_days");
query.put("country", country);
query.put("service", service);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": {
"Days": 30,
"Status": 1,
"Message": ""
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | Minimum rental period and its availability result. |
| **`data.Days`** | integer | Minimum rental period in days. |
| **`data.Status`** | integer | Availability status returned by the server, separate from the top-level status. |
| **`data.Message`** | string | Availability message returned by the server. |
| **`msg`** | string | Error message when status is 0. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Multi-service count (/en/docs/rental/multi-service-count)
GET{"https://smspva.com/api/rent.php?method=get_count_multi"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
You can call this method without an API key.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "get_count_multi" | Method name |
| **`country`** | query | string | Yes | "KZ" | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`services`** | query | string | Yes | "opt1,opt2" | Services codes separated by commas [Services list](/en/docs/rental/reference-data) |
| **`dtype`** | query | string | No | "week" | Type of period: week or month |
| **`dcount`** | query | integer | No | 1 | Count type of period, i.e. if **`dtype`**=week then counts of weeks |
## How to use this method [#how-to-use-this-method]
Check how many numbers support your combination of services. Send the codes together in **`services`**. Always pass **`dtype`** and **`dcount`** explicitly for this method; its backend defaults are not reliable.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_count_multi" \
--data-urlencode "country=KZ" \
--data-urlencode "services=opt1,opt2" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt1,opt2";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "get_count_multi",
"country": country,
"services": services,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt1,opt2";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "get_count_multi",
"country": country,
"services": services,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
services = os.environ.get("SMSPVA_RENTAL_SERVICES", "opt1,opt2")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "get_count_multi",
"country": country,
"services": services,
"dtype": dtype,
"dcount": dcount
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_count_multi',
'country' => $country,
'services' => $services,
'dtype' => $dtype,
'dcount' => $dcount
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
services := env("SMSPVA_RENTAL_SERVICES", "opt1,opt2")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "get_count_multi")
query.Set("country", country)
query.Set("services", services)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var services = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICES") ?? "opt1,opt2";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "get_count_multi",
["country"] = country,
["services"] = services,
["dtype"] = dtype,
["dcount"] = dcount
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String services = env("SMSPVA_RENTAL_SERVICES", "opt1,opt2");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "get_count_multi");
query.put("country", country);
query.put("services", services);
query.put("dtype", dtype);
query.put("dcount", dcount);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": {
"count": 10
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | |
| **`data.count`** | integer | |
| **`msg`** | string | Error message when status is 0. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Rental orders (/en/docs/rental/orders)
GET{"https://smspva.com/api/rent.php?method=orders"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
Send **apikey** as a required **query parameter**.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "orders" | Method name |
| **`apikey`** | query | string | Yes | **`SMSPVA_API_KEY`** | Your API key You can find it on the website in the top right drop-down menu in the Profile and APIKEY section |
## How to use this method [#how-to-use-this-method]
View your active rentals, their current state and extension options. Use an order’s ID to [activate](/en/docs/rental/activate), [read SMS](/en/docs/rental/sms) or [extend it](/en/docs/rental/prolong). Completed rentals and restoration eligibility are in [Rental history](/en/docs/rental/history).
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=orders" \
--data-urlencode "apikey=$SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
query = {
"method": "orders"
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'orders'
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
query := url.Values{}
query.Set("method", "orders")
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var query = new Dictionary {
["method"] = "orders"
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
Map query = new LinkedHashMap<>();
query.put("method", "orders");
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": [
{
"id": 40300,
"scode": "opt16",
"sname": "Instagram",
"state": 0,
"pnumber": "9096068511",
"ccode": "+7",
"cname": "KZ",
"hasnewsms": false,
"until": 1587552240,
"canprolong": true,
"canprolongmax": 162,
"canprolonguntil": 1634883780,
"lastonline": 1586947920
}
]
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | array<object> | |
| **`data[].id`** | integer | ID of order |
| **`data[].scode`** | string | Service code [Services list](/en/docs/rental/reference-data) |
| **`data[].sname`** | string | Service name |
| **`data[].state`** | integer | Order state: 0 - not active, 1 - active, 2 - activating, -1 - not in system |
| **`data[].pnumber`** | string | Phone number without country code |
| **`data[].ccode`** | string | Digital country code |
| **`data[].cname`** | string | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`data[].hasnewsms`** | boolean | New SMS received for this order |
| **`data[].until`** | integer | UNIX timestamp of expire date |
| **`data[].canprolong`** | boolean | Is this order available for prolongation? |
| **`data[].canprolongmax`** | integer | Maximum number of days available for prolongation. This is the limit - you cannot extend beyond this number of days. |
| **`data[].canprolonguntil`** | integer | Unix timestamp showing the deadline until which you can prolong the order. After this date, prolongation is not available. |
| **`data[].lastonline`** | integer | Unix timestamp of last online date of number |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Prolong by days (/en/docs/rental/prolong-max)
GET{"https://smspva.com/api/rent.php?method=prolong_max"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
This request can modify a rental or incur charges. If the response is lost, check your orders and history before trying again: the change may already have been made. The examples do not retry automatically.
## Authentication [#authentication]
Send **apikey** as a required **query parameter**.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "prolong_max" | Method name |
| **`apikey`** | query | string | Yes | **`SMSPVA_API_KEY`** | Your API key You can find it on the website in the top right drop-down menu in the Profile and APIKEY section |
| **`id`** | query | integer | Yes | 123 | ID of order |
| **`dtype`** | query | string | Yes | "day" | Duration type - must always be "day" |
| **`dcount`** | query | integer | Yes | 5 | Number of days to extend (1-6). The requested extension must also fit within the order-specific **`canprolongmax`** limit. |
## How to use this method [#how-to-use-this-method]
Extend the rental by days with **`dtype=day`** and **`dcount`** from **1–6**. Check **`canprolong`**, **`canprolongmax`** and **`canprolonguntil`** in [Rental orders](/en/docs/rental/orders) first. The extension must stay within the limits of that order.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=prolong_max" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID" \
--data-urlencode "dtype=day" \
--data-urlencode "dcount=5"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "day";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "5";
const query = new URLSearchParams({
"method": "prolong_max",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "day";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "5";
const query = new URLSearchParams({
"method": "prolong_max",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "day")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "5")
query = {
"method": "prolong_max",
"id": id,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'prolong_max',
'id' => $id,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "day")
dcount := env("SMSPVA_RENTAL_DCOUNT", "5")
query := url.Values{}
query.Set("method", "prolong_max")
query.Set("id", id)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "day";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "5";
var query = new Dictionary {
["method"] = "prolong_max",
["id"] = id,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "day");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "5");
Map query = new LinkedHashMap<>();
query.put("method", "prolong_max");
query.put("id", id);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Response with order max prolongation status
**application/json**
**Successfully extended by up to 7 days**
```json
{
"status": 1
}
```
**Incorrect order id**
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
**Order not found**
```json
{
"status": 0,
"msg": "Order not found"
}
```
**Invalid duration parameters**
```json
{
"status": 0,
"msg": "More than 7 days or type is not day"
}
```
**Insufficient funds in account**
```json
{
"status": 0,
"msg": "Insufficient balance"
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Prolong rental (/en/docs/rental/prolong)
GET{"https://smspva.com/api/rent.php?method=prolong"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
This request can modify a rental or incur charges. If the response is lost, check your orders and history before trying again: the change may already have been made. The examples do not retry automatically.
## Authentication [#authentication]
Send **apikey** as a required **query parameter**.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "prolong" | Method name |
| **`apikey`** | query | string | Yes | **`SMSPVA_API_KEY`** | Your API key You can find it on the website in the top right drop-down menu in the Profile and APIKEY section |
| **`id`** | query | integer | Yes | 123 | ID of order |
| **`dtype`** | query | string | Yes | "week" | Type of period: week or month |
| **`dcount`** | query | integer | Yes | 1 | Count type of period, i.e. if **`dtype`**=week then counts of weeks |
## How to use this method [#how-to-use-this-method]
Extend the rental by the requested number of weeks or months. Check **`canprolong`**, **`canprolongmax`** and **`canprolonguntil`** in [Rental orders](/en/docs/rental/orders) first. The extension must stay within the limits of that order.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=prolong" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "prolong",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "prolong",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "prolong",
"id": id,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'prolong',
'id' => $id,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "prolong")
query.Set("id", id)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "prolong",
["id"] = id,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "prolong");
query.put("id", id);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Response with order prolongation status
**application/json**
**Successful prolongation**
```json
{
"status": 1
}
```
**Incorrect order id**
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
**Order not found**
```json
{
"status": 0,
"msg": "Order not found"
}
```
**Incorrect duration type**
```json
{
"status": 0,
"msg": "Incorrect duration type. Available types: week, month"
}
```
**Incorrect duration count**
```json
{
"status": 0,
"msg": "Incorrect duration count. Min 7 days. Max 90 days."
}
```
**Insufficient funds in account**
```json
{
"status": 0,
"msg": "Insufficient balance"
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Countries & services (/en/docs/rental/reference-data)
Choose rental country and service codes here, then compare prices, providers, duration and stock before creating an order. These codes and available services can differ from Activation V2.
The lists load when you open the page and refresh every **five minutes** while visible. The source uses a five-minute cache, so a recent change may take a little time to appear.
[Live JSON](/reference-data.php) · [Data by provider](/en/docs/rental/data-by-provider)
# Restore precalculation (/en/docs/rental/restore-precalculation)
GET{"https://smspva.com/api/rent.php?method=restore_user_precalc"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
Send **apikey** as a required **query parameter**.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "restore_user_precalc" | Method name |
| **`apikey`** | query | string | Yes | **`SMSPVA_API_KEY`** | Your API key You can find it on the website in the top right drop-down menu in the Profile and APIKEY section |
| **`id`** | query | integer | Yes | "" | ID of order |
## How to use this method [#how-to-use-this-method]
Check the cost, duration and availability of restoring an expired rental. Get its ID from [Rental history](/en/docs/rental/history), where **`isAvailForRestore`** must be **true**. This calculation is the first step; call [Restore rental](/en/docs/rental/restore) to complete the restoration.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=restore_user_precalc" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user_precalc",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user_precalc",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "restore_user_precalc",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'restore_user_precalc',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "restore_user_precalc")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "restore_user_precalc",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "restore_user_precalc");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": {
"ccode": "LT",
"scode": "opt9",
"price": 1.5,
"sname": "Instagram",
"pnumber": "37067787324",
"outdays": 5,
"orderid": 857191,
"prolongTo": 30
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | |
| **`data.ccode`** | string | Country code of number [Countries list](/en/docs/rental/reference-data) |
| **`data.scode`** | string | Service code [Services list](/en/docs/rental/reference-data) |
| **`data.price`** | number | Cost to restore this order |
| **`data.sname`** | string | Service name |
| **`data.pnumber`** | string | rented phone number with country code without plus sign |
| **`data.outdays`** | integer | Number of days since the order expired |
| **`data.orderid`** | integer | ID of order |
| **`data.prolongTo`** | integer | Number of days for which the restored order will be active |
| **`msg`** | string | Error message when status is 0. |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Restore rental (/en/docs/rental/restore)
GET{"https://smspva.com/api/rent.php?method=restore_user"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
This request can modify a rental or incur charges. If the response is lost, check your orders and history before trying again: the change may already have been made. The examples do not retry automatically.
## Authentication [#authentication]
Send **apikey** as a required **query parameter**.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "restore_user" | Method name |
| **`apikey`** | query | string | Yes | **`SMSPVA_API_KEY`** | Your API key You can find it on the website in the top right drop-down menu in the Profile and APIKEY section |
| **`id`** | query | integer | Yes | "" | ID of order |
## How to use this method [#how-to-use-this-method]
Restore an eligible completed rental. Get its ID from [Rental history](/en/docs/rental/history), check **`isAvailForRestore`**, and review [cost and duration](/en/docs/rental/restore-precalculation) first.
On success, **`status=1`** and **`data.id`** contains the **new** restored order ID. Use it to find the rental in [Rental orders](/en/docs/rental/orders). If **`status=0`**, read **`msg`** for the reason.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=restore_user" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "restore_user",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'restore_user',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "restore_user")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "restore_user",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "restore_user");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
The response contains a restored order ID when the request succeeds, or an error message when it fails.
**application/json**
**Successful restore**
```json
{
"status": 1,
"data": {
"id": 123456
}
}
```
**Incorrect order ID**
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
**Order not found**
```json
{
"status": 0,
"msg": "Order not found"
}
```
**Not enough balance**
```json
{
"status": 0,
"msg": "NOBALANCE_12.50"
}
```
**Number is busy**
```json
{
"status": 0,
"msg": "The number is busy, there is already an order for this service"
}
```
**Success**
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Request status. **`1`** means the order was restored successfully. |
| **`data`** | object | Restored order data. |
| **`data.id`** | integer | New restored order ID. |
Required: **`status`**, **`data`**
**Error**
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Request status. **`0`** means the restore request failed. |
| **`msg`** | string | Error message. |
Required: **`status`**, **`msg`**
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Rental SMS (/en/docs/rental/sms)
GET{"https://smspva.com/api/rent.php?method=sms"}
Send a **GET** request and check **`status`** in the JSON response: **1** means success and **0** means failure, even with HTTP **200**. If it fails, read **`msg`** for the reason.
## Authentication [#authentication]
Send **apikey** as a required **query parameter**.
## Parameters [#parameters]
| Name | Location | Type | Required | Example | Description |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Yes | "sms" | Method name |
| **`apikey`** | query | string | Yes | **`SMSPVA_API_KEY`** | Your API key You can find it on the website in the top right drop-down menu in the Profile and APIKEY section |
| **`id`** | query | integer | Yes | 123 | ID of order |
## How to use this method [#how-to-use-this-method]
Read messages for a rental using its ID from [Rental orders](/en/docs/rental/orders). Before sending a message to that number, [activate the order](/en/docs/rental/activate) and confirm its state in the order list.
## Request examples [#request-examples]
[Environment and dependencies](/en/docs/rental/examples). Each example encodes query values and allows 30 seconds for the request. Check HTTP and JSON **`status`** before using **`data`**. cURL prints the response for you to check; Java uses Jackson to read the JSON.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=sms" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "sms",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "sms",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "sms",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'sms',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "sms")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "sms",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "sms");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Responses [#responses]
Check the response that matches your request. Example values and dates are illustrative. Optional fields can depend on the outcome or the response format you selected.
### HTTP 200 [#http-200]
Success
**application/json**
**Illustrative response**
```json
{
"status": 1,
"data": {
"SmsList": [
{
"text": "Code Instagram: 671 094.",
"sender": "FACEBOOK",
"date": 1586948100
}
],
"OtherSms": []
}
}
```
| Name | Type | Description |
| --- | --- | --- |
| **`status`** | integer | Status of the response: 1 for success, 0 for failure |
| **`data`** | object | |
| **`data.SmsList`** | array<object> | List of received SMS |
| **`data.SmsList[].text`** | string | Text of SMS |
| **`data.SmsList[].sender`** | string | Sender of the SMS |
| **`data.SmsList[].date`** | integer | Unix timestamp of receiving date |
| **`data.OtherSms`** | array<unspecified> | List of other SMS |
## Related guides [#related-guides]
- [Rental API](/en/docs/rental)
- [Countries & services](/en/docs/rental/reference-data)
- [Rental workflow](/en/docs/rental/workflow)
- [Errors](/en/docs/rental/errors)
- [Source OpenAPI](/openapi/rental.json)
# Rental workflow (/en/docs/rental/workflow)
## 1. Select a country, service and duration [#1-select-a-country-service-and-duration]
Start with the [live rental lists](/en/docs/rental/reference-data) and [Rental countries](/en/docs/rental/countries). Use [Rental data by provider](/en/docs/rental/data-by-provider) to compare service codes, provider counts and prices for the same country and duration.
For multi-service rentals, send comma-separated codes in **services** and check [Multi-service count](/en/docs/rental/multi-service-count). Pass **dtype** and **dcount** explicitly to that method, as the source documentation recommends. Most duration methods use **week** or **month**; do not assume every method supports days.
## 2. Create the rental [#2-create-the-rental]
Use [Create rental](/en/docs/rental/create) or [Create multi-service rental](/en/docs/rental/create-multi). Save **data.id**, **pnumber**, **ccode** and **until**. These are rental identifiers, not Activation V2 order IDs.
Both requests use GET as documented. They may create a paid order. If a timeout leaves the result uncertain, inspect [Rental orders](/en/docs/rental/orders) before repeating the request.
## 3. Activate before sending SMS [#3-activate-before-sending-sms]
Call [Activate rental](/en/docs/rental/activate) with the rental order ID. Then inspect **state** in [Rental orders](/en/docs/rental/orders):
| state | Meaning from the documentation |
| --- | --- |
| 0 | Not active |
| 1 | Active |
| 2 | Activating |
| -1 | Not in system |
Only send an SMS after the order is active. A successful activate request does not replace checking the order state.
## 4. Read messages [#4-read-messages]
Call [Rental SMS](/en/docs/rental/sms). Inspect **status=1**, then read **data.SmsList** and **data.OtherSms**. An empty list is a successful result with no messages in that list. Do not use the Activation V2 HTTP 202 waiting logic here.
The method returns message lists, not a documented “consume next message” cursor. Repeated reads can include messages you have already processed. Keep application-side processing state.
For polling, space requests, stop when your task is complete or the rental expires, and handle transport errors separately. Handle rate-limit responses from the method you are calling, and set a deadline for your checks. The endpoint examples make one request and do not retry automatically.
## 5. Extend, change or remove a rental [#5-extend-change-or-remove-a-rental]
- [Add service](/en/docs/rental/add-service) requires the rental ID, **pnumber** and service; **rent_days** is optional as documented.
- [Prolong](/en/docs/rental/prolong) uses week/month periods. Inspect **canprolong**, **canprolongmax** and **canprolonguntil** first.
- [Prolong by days](/en/docs/rental/prolong-max) requires **dtype=day**, **dcount=1–6**, within the order-specific **canprolongmax** limit.
- [Remove order](/en/docs/rental/delete) uses GET with **method=delete**, not HTTP DELETE.
These methods have different purposes and are not called automatically by the examples.
## 6. Restore a completed rental [#6-restore-a-completed-rental]
Read [Rental history](/en/docs/rental/history) and check **isAvailForRestore**. Call [Restore precalculation](/en/docs/rental/restore-precalculation) to inspect cost and duration, then [Restore rental](/en/docs/rental/restore).
On success, **data.id** is the new restored order ID. Use that ID with subsequent rental operations and inspect current orders. A failed restore may return HTTP 200 with **status=0** and **msg**; inspect the JSON before declaring success.
## Time fields and formats [#time-fields-and-formats]
Creation examples document **until** as a string, while order-list examples use an integer. Keep the source types for each response. Expiry and prolongation deadlines are Unix timestamps in seconds; the Activation V2 **orderExpireIn** model does not apply.
# SDKs & libraries (/en/docs/sdks)
## Choose an SDK [#choose-an-sdk]
The SDKs cover all 56 methods in Activation V2, Rental and Private Email. Choose the language and execution model that fits your application. Alternative API is excluded.
All six SDKs are published alpha releases, with source in the official SMSPVA GitHub repositories. Choose a package below to install it from its public registry. All SDKs use MIT.
| Package | Requirements | Status | Release |
| --- | --- | --- | --- |
| [Python SDK on PyPI](https://pypi.org/project/smspva-sdk/) | Python 3.10 or later | Published alpha, sync and async | **`0.1.0a2`** |
| [JavaScript / TypeScript SDK on npm](https://www.npmjs.com/package/smspva-sdk) | Node.js 22.16 or later | Published alpha, ESM and CommonJS | **`0.1.0-alpha.2`** |
| [PHP SDK](https://packagist.org/packages/smspva/sdk) | PHP 8.0+, cURL and JSON | Published alpha, synchronous | **`0.1.0-alpha.1`** |
| [Go SDK](https://pkg.go.dev/github.com/SMSPVA/smspva-go) | Go 1.22+ | Published alpha, synchronous with context | **`v0.1.0-alpha.1`** |
| [C# / .NET](https://www.nuget.org/packages/Smspva.Sdk/0.1.0-alpha.1) | .NET 8+ | Published alpha, asynchronous with CancellationToken | **`0.1.0-alpha.1`** |
| [Java SDK](https://central.sonatype.com/artifact/com.smspva/smspva-sdk/0.1.0-alpha.1) | Java 17+ | Published alpha, synchronous | **`0.1.0-alpha.1`** |
## Versions and updates [#versions-and-updates]
The published SDKs are alpha releases. Pin a version when you need reproducible installs, and review the repository changelog before upgrading. Python uses **`0.1.0a2`**; JavaScript/TypeScript uses **`0.1.0-alpha.2`**; PHP, Go, C#/.NET and Java use **`0.1.0-alpha.1`** (with the **`v`** prefix in Go commands). These are prerelease versions, not stable releases.
## Python [#python]
Install the Python SDK from [PyPI](https://pypi.org/project/smspva-sdk/). Use **`--pre`** to include alpha releases:
```sh
python -m pip install --pre smspva-sdk
```
To pin the current release, use **`python -m pip install smspva-sdk==0.1.0a2`**. Source code, the README and issue tracking are in [SMSPVA/smspva-python on GitHub](https://github.com/SMSPVA/smspva-python).
Use **`SMSPVA`** in a synchronous application. This example reads your Activation balance and fetches the current Rental countries and Email providers:
```python
import os
from smspva import SMSPVA
with SMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
print(client.activation.get_balance())
print(client.rental.get_countries())
print(client.email.get_providers())
```
For an asynchronous application, use **`AsyncSMSPVA`** and await the same methods:
```python
import asyncio
import os
from smspva import AsyncSMSPVA
async def main():
async with AsyncSMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
print(await client.activation.get_balance())
print(await client.rental.get_countries())
print(await client.email.get_providers())
asyncio.run(main())
```
The context manager closes the connection pool for you. If you manage the client yourself, call **`close()`** or **`await aclose()`** when you finish.
## JavaScript and TypeScript [#javascript-and-typescript]
Install the JavaScript and TypeScript SDK from [npm](https://www.npmjs.com/package/smspva-sdk). The **`alpha`** tag selects the latest alpha release:
```sh
npm install smspva-sdk@alpha
```
To pin the current release, use **`npm install smspva-sdk@0.1.0-alpha.2`**. Source code, the README and issue tracking are in [SMSPVA/smspva-js on GitHub](https://github.com/SMSPVA/smspva-js).
```ts
import { SMSPVA } from 'smspva-sdk';
const client = new SMSPVA({ apiKey: process.env.SMSPVA_API_KEY });
console.log(await client.activation.getBalance());
console.log(await client.rental.getCountries());
console.log(await client.email.getProviders());
```
The same code works in JavaScript. For CommonJS, import with **`const { SMSPVA } = require('smspva-sdk')`**. Run the SDK on your server and keep the API key out of browser code.
## PHP [#php]
Install the [PHP SDK from Packagist](https://packagist.org/packages/smspva/sdk) with Composer:
```sh
composer require "smspva/sdk:^0.1@alpha"
```
To pin this release, use **`composer require smspva/sdk:0.1.0-alpha.1`**. Source code, the README and issue tracking are in [SMSPVA/smspva-php on GitHub](https://github.com/SMSPVA/smspva-php).
```php
activation->getBalance());
print_r($client->rental->getCountries());
print_r($client->email->getProviders());
```
PHP methods accept parameter arrays with generated PHPDoc shapes. Responses are associative arrays. The client is synchronous and requires the cURL extension.
## Go [#go]
Install the [Go SDK](https://pkg.go.dev/github.com/SMSPVA/smspva-go) from its tagged module:
```sh
go get github.com/SMSPVA/smspva-go@v0.1.0-alpha.1
```
Source code, the README and issue tracking are in [SMSPVA/smspva-go on GitHub](https://github.com/SMSPVA/smspva-go). The SDK uses only the standard library.
The Go SDK is a versioned GitHub module. **`pkg.go.dev`** displays its README and generated package documentation; it is not a separate upload destination. No pkg.go.dev account is needed to install it. New versions are identified by Git tags in the official repository.
```go
package main
import (
"context"
"fmt"
"log"
"os"
smspva "github.com/SMSPVA/smspva-go"
)
func printResult(response smspva.Response, err error) {
if err != nil { log.Fatal(err) }
fmt.Println(string(response.Body))
}
func main() {
client, err := smspva.New(smspva.Options{APIKey: os.Getenv("SMSPVA_API_KEY")})
if err != nil { log.Fatal(err) }
defer client.CloseIdleConnections()
ctx := context.Background()
printResult(client.Activation.GetBalance(ctx))
printResult(client.Rental.GetCountries(ctx))
printResult(client.Email.GetProviders(ctx))
}
```
Save the program as **`main.go`** and run **`go run .`**. Methods take a **`context.Context`**, typed parameter structs where needed, and return the unchanged JSON in **`Response.Body`**.
## C# / .NET [#c--net]
Install the [.NET SDK from NuGet](https://www.nuget.org/packages/Smspva.Sdk/0.1.0-alpha.1). Source, the README and issue tracking are in [SMSPVA/smspva-dotnet on GitHub](https://github.com/SMSPVA/smspva-dotnet):
```sh
dotnet add package Smspva.Sdk --version 0.1.0-alpha.1
```
```csharp
using System;
using Smspva;
using var client = new SmspvaClient(Environment.GetEnvironmentVariable("SMSPVA_API_KEY"));
Console.WriteLine(await client.Activation.GetBalanceAsync());
Console.WriteLine(await client.Rental.GetCountriesAsync());
Console.WriteLine(await client.Email.GetProvidersAsync());
```
C# methods are asynchronous and accept a **`CancellationToken`**. Request records are typed; responses are **`JsonElement`** values.
## Java [#java]
Install the [Java SDK from Maven Central](https://central.sonatype.com/artifact/com.smspva/smspva-sdk/0.1.0-alpha.1) by adding this dependency to your application’s **`pom.xml`**:
```xml
com.smspva
smspva-sdk
0.1.0-alpha.1
```
```java
import com.smspva.sdk.SmsPva;
public class Example {
public static void main(String[] args) {
try (SmsPva client = new SmsPva(System.getenv("SMSPVA_API_KEY"))) {
System.out.println(client.activation().getBalance());
System.out.println(client.rental().getCountries());
System.out.println(client.email().getProviders());
}
}
}
```
Source code, the README and issue tracking are in [SMSPVA/smspva-java on GitHub](https://github.com/SMSPVA/smspva-java). Java methods are synchronous, accept typed **`Requests`** records, and return **`JsonNode`**. This alpha has no Java async wrapper or polling helper.
## Parameters and responses [#parameters-and-responses]
Choose country, service and provider codes from the current reference lists. For example, call **`email.get_providers()`** in Python or **`email.getProviders()`** in JavaScript to load the providers, then pass the chosen **`pcode`** to **`get_data(pcode=...)`** or **`getData({ pcode: ... })`**. Public reference methods work without an API key and never send the client's key.
The SDKs preserve documented HTTP methods, wire parameter names, response codes and JSON value types. Python and JavaScript include generated response types. PHP returns associative arrays, Go returns raw JSON in **`Response.Body`**, C# uses **`JsonElement`**, and Java uses **`JsonNode`**. Their request arguments are documented or typed for each language.
For Rental's multi-service count method, provide **`dtype`** and **`dcount`** explicitly. The SDK requires both because the API documentation warns against relying on the backend defaults for this method.
## Waiting for SMS and handling errors [#waiting-for-sms-and-handling-errors]
Activation's **`receive_sms`** / **`receiveSms`** returns the original pending response for HTTP **`202`** and **`SMS_NOT_YET_RECEIVED`**. Check it with **`is_pending`** / **`isPending`**. Email creation likewise returns the original **`status=2`** no-stock result; use **`is_no_stock`** / **`isNoStock`** to recognise it.
For repeated SMS checks, use **`activation.wait_for_sms`** in Python or **`activation.waitForSms`** in JavaScript. Save the order's expiry when you obtain the number, then pass that same deadline as **`expires_at`** (Unix seconds) or **`expiresAt`** (Unix milliseconds). The helper waits at least five seconds between pending responses and stops at the deadline or on an error. It never creates or cancels orders. Receiving a new SMS can trigger payment.
A single **`receive_sms`** / **`receiveSms`** call makes one HTTP request. The Python and JavaScript waiting helpers send the first request immediately, then wait five seconds after each pending response before checking again. Set **`interval=15`** in Python or **`intervalMs: 15_000`** in JavaScript for a 15-second pause. This minimum interval is a helper policy, not an API-wide rate limit. **`await`** waits for the helper result while allowing other asynchronous tasks to run during requests and pauses; the synchronous Python client blocks the calling thread.
Python, JavaScript and PHP report API failures through **`ApiError`**; C# and Java use **`ApiException`**, and Go returns an **`APIError`**. These keep the HTTP status, API code and original response. Protocol and transport errors are separate. C# supports cancellation tokens, and Go supports context cancellation.
No request is retried automatically. If a paid or state-changing request loses its connection, its outcome may be unknown. Check your current orders before repeating it to avoid a duplicate purchase. A GET method can still change state or trigger a charge.
The default timeout is 30 seconds. Python applies it to each HTTPX network operation; JavaScript applies it to the whole request, including reading the response body. Override it with **`timeout`** in Python or **`timeoutMs`** in JavaScript. JavaScript also accepts an **`AbortSignal`** through the **`signal`** option.
PHP, Go and C# also bound the complete request by default. Java uses network-operation timeouts, like Python, rather than a strict whole-response deadline. Java and PHP are synchronous. Check the SDK README for timeout options and error types in your language.
You can continue using the [HTTP examples](/en/docs/quickstart) alongside the SDKs. Each API method page remains the reference for its parameters, response codes and important warnings.
# Flujo de activación (/es/docs/activation-workflow)
## 1. Selecciona los códigos y el tipo [#1-selecciona-los-códigos-y-el-tipo]
Consulta [países y servicios](/es/docs/reference-data), [operadores](/es/docs/api/operators), [disponibilidad](/es/docs/api/country-countnumbers) y [precios](/es/docs/api/service-price). Comprueba los [permisos](/es/docs/message-types): **`voice=0`** SMS, 1 caller-ID, 2 voz.
Los precios y la disponibilidad no reservan un número. En operadores donantes, 9999 indica que se desconoce el recuento exacto.
## 2. Obtén un número [#2-obtén-un-número]
Usa [Obtener número](/es/docs/api/get-number), o [Obtener número por operador](/es/docs/api/get-number-by-operator) si necesitas uno concreto.
Guarda **`data.orderId`**: lo necesitarás para recibir mensajes y gestionar el pedido. La respuesta también incluye **`data.orderExpireIn`**, los segundos que quedan hasta que venza. Calcula el vencimiento una sola vez:
```text
const expiresAt = Date.now() + numberResult.data.orderExpireIn * 1000;
```
Conserva este vencimiento al consultar los mensajes: todas las consultas usan el mismo plazo. Usa la duración devuelta por la API en vez de suponer que siempre son diez minutos.
Si se agota el tiempo de espera, revisa [Pedidos actuales](/es/docs/api/orders) antes de pedir otro número: el primero puede haberse creado. No hay una clave de idempotencia documentada que evite duplicados.
## 3. Espera el resultado [#3-espera-el-resultado]
Consulta [Receive SMS](/es/docs/api/receive-sms) con **`orderId`**. También obtiene voz y caller-ID sin parámetro **`voice`** adicional.
| Respuesta | Acción |
| --- | --- |
| 200 | Usa **`data.sms`** y termina el bucle |
| 202 + SMS_NOT_YET_RECEIVED | Espera y repite dentro del plazo |
| 410 + ORDER_CLOSED | Detén el bucle; el pedido está cerrado |
| Otro error | Gestiona el error documentado |
La respuesta de espera incluye **`error`**: comprueba primero si es **`SMS_NOT_YET_RECEIVED`** antes de tratarla como un fallo. Leer un SMS recién recibido puede generar el cobro.
Este ejemplo espera cinco segundos entre consultas; es configuración del cliente, no un nuevo límite de la API. Respeta los errores de límite y el plazo. Los fallos de conexión y respuestas no JSON detienen el bucle.
```js
// Node.js 22.16+. No automatic retries after transport errors or terminal responses.
export async function waitForSms({ apiKey, orderId, expiresAt, intervalMs = 5000 }, {
fetchImpl = fetch,
now = Date.now,
sleep = ms => new Promise(resolve => setTimeout(resolve, ms)),
baseUrl = 'https://api.smspva.com',
} = {}) {
if (!apiKey || !/^\d+$/.test(String(orderId))) throw new Error('Set your API key and order ID');
if (!Number.isFinite(expiresAt) || expiresAt <= now()) throw new Error('Order deadline has passed');
if (!Number.isFinite(intervalMs) || intervalMs < 5000) throw new Error('Use a polling interval of at least 5000 ms in this example');
while (now() < expiresAt) {
const remaining = expiresAt - now();
const response = await fetchImpl(`${baseUrl}/activation/sms/${encodeURIComponent(orderId)}`, {
headers: { apikey: apiKey },
signal: AbortSignal.timeout(Math.max(1, Math.floor(Math.min(30_000, remaining)))),
});
const result = await response.json();
if (response.status === 202 && result.statusCode === 202 && result.error?.type === 'SMS_NOT_YET_RECEIVED') {
const delay = Math.min(intervalMs, expiresAt - now());
if (delay <= 0) break;
await sleep(delay);
continue;
}
if (response.status !== 200 || result.error || result.statusCode !== 200) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
}
return result.data;
}
throw new Error('No result before the order deadline');
}
```
Guarda la función como poll-sms.mjs y llámala con el plazo calculado al recibir el número:
```text
import { waitForSms } from './poll-sms.mjs';
const data = await waitForSms({ apiKey, orderId, expiresAt });
console.log(data.sms);
```
[Descargar función](/examples/poll-sms.mjs)
## 4. Gestiona el pedido [#4-gestiona-el-pedido]
- [Clear SMS](/es/docs/api/clear-sms): borra el SMS actual para recibir otro. Conserva **`orderExpireIn`**. El 404 / NO_SMS_TO_CLEAN no confirma un borrado.
- [Stop SMS](/es/docs/api/stop-sms): detiene la recepción.
- [Cancel order](/es/docs/api/cancel-order): cancela el pedido.
- [Block number](/es/docs/api/block-number): marca el número como no operativo.
- [Number status](/es/docs/api/number-status): comprueba un número utilizado antes para el mismo servicio.
No son acciones intercambiables ni se ejecutan automáticamente al agotar el tiempo. Consulta las respuestas de cada método.
# Todos los precios (/es/docs/api/all-service-prices)
GET{"https://api.smspva.com/activation/servicesprices"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`voice`** | query | integer | No | Tipo: 0 SMS, 1 identificación de llamada, 2 voz. Valor predeterminado: 0. (**`enum: [0,1,2]`**; **`default: 0`**) |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Compara los precios de los servicios entre países. Para una consulta más concreta, usa [Precio del servicio](/es/docs/api/service-price) o [Precios por país y operador](/es/docs/api/country-operator-prices). Comprueba la [disponibilidad](/es/docs/api/countnumbers) antes de pedir un número.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/servicesprices?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/servicesprices" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/servicesprices" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/servicesprices" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/servicesprices" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/servicesprices" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/servicesprices" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": [
{
"service": "opt0",
"serviceDescription": "myopinions & erewards",
"country": "CY",
"price": "0.50"
}
]
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | array<object> | Datos de respuesta |
| **`data[].service`** | string | Servicio |
| **`data[].serviceDescription`** | string | Descripción del servicio. |
| **`data[].country`** | string | País |
| **`data[].price`** | string | Precio. |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Consultar saldo (/es/docs/api/balance)
GET{"https://api.smspva.com/activation/balance"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
Sin parámetros de ruta o consulta. No requiere cuerpo.
## Cómo usar este método [#cómo-usar-este-método]
Consulta el saldo disponible en tu cuenta. La respuesta devuelve **`data.balance`** como cadena; conserva ese tipo al mostrar el importe.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/balance" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/balance";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/balance";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/balance"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/balance"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/balance";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/balance";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 400 | Falta la cabecera **`apikey`**, está vacía o su longitud no es válida. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"balance": "10.50"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.balance`** | string | Saldo |
HTTP 400
Falta la cabecera **`apikey`**, está vacía o su longitud no es válida.
**Respuesta ilustrativa**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Bloquear número (/es/docs/api/block-number)
PUT{"https://api.smspva.com/activation/blocknumber/{orderid}"}
**Esta solicitud puede modificar un pedido o generar cargos.** Los ejemplos no la repiten automáticamente. Leer un SMS recién recibido puede generar el cobro, aunque el método use GET.
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`orderid`** | path | integer | Sí | ID del pedido |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Marca como no operativo el número de este **`orderid`**.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
- **`SMSPVA_ORDER_ID`**: **`orderid`** (obligatorio).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_ORDER_ID:?Set SMSPVA_ORDER_ID to your orderid}"
curl --fail-with-body --max-time 30 --request PUT \
--url "https://api.smspva.com/activation/blocknumber/${SMSPVA_ORDER_ID}" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/blocknumber/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/blocknumber/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_ORDER_ID"]
url = "https://api.smspva.com/activation/blocknumber/" + quote(orderid, safe="") + ""
request = Request(url, method="PUT", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'PUT',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_ORDER_ID", "")
endpoint := "https://api.smspva.com/activation/blocknumber/" + url.PathEscape(orderid) + ""
request, err := http.NewRequest("PUT", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_ORDER_ID");
var url = "https://api.smspva.com/activation/blocknumber/" + Uri.EscapeDataString(orderid) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("PUT"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_ORDER_ID", null);
String url = "https://api.smspva.com/activation/blocknumber/" + segment(orderid) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("PUT", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 405 | Formato de número no válido |
| 406 | El ID del pedido no es válido o no se encontró. |
| 411 | Acceso limitado por karma bajo o exceso de solicitudes. |
| 501 | El servidor no pudo procesar la solicitud. |
| 503 | El servidor está sobrecargado. Inténtalo más tarde. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.orderId`** | integer | ID del pedido |
HTTP 405
Formato de número no válido
**Respuesta ilustrativa**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Datos de respuesta |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 406
El ID del pedido no es válido o no se encontró.
**Respuesta ilustrativa**
```json
{
"statusCode": 406,
"error": {
"type": "ORDER_NOT_FOUND",
"description": "Order not found."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Datos de respuesta |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 411
Acceso limitado por karma bajo o exceso de solicitudes.
**Respuesta ilustrativa**
```json
{
"statusCode": 411,
"error": {
"type": "ACCESS_LIMITED",
"description": "Access is temporary limited."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 501
El servidor no pudo procesar la solicitud.
**Respuesta ilustrativa**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_FAIL",
"description": "Server failed to process request"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Datos de respuesta |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 503
El servidor está sobrecargado. Inténtalo más tarde.
**Respuesta ilustrativa**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Cancelar pedido (/es/docs/api/cancel-order)
PUT{"https://api.smspva.com/activation/cancelorder/{orderid}"}
**Esta solicitud puede modificar un pedido o generar cargos.** Los ejemplos no la repiten automáticamente. Leer un SMS recién recibido puede generar el cobro, aunque el método use GET.
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`orderid`** | path | integer | Sí | ID del pedido |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Cancela el pedido de activación indicado en **`orderid`**. Comprueba la respuesta para confirmar la cancelación.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
- **`SMSPVA_ORDER_ID`**: **`orderid`** (obligatorio).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_ORDER_ID:?Set SMSPVA_ORDER_ID to your orderid}"
curl --fail-with-body --max-time 30 --request PUT \
--url "https://api.smspva.com/activation/cancelorder/${SMSPVA_ORDER_ID}" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/cancelorder/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/cancelorder/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_ORDER_ID"]
url = "https://api.smspva.com/activation/cancelorder/" + quote(orderid, safe="") + ""
request = Request(url, method="PUT", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'PUT',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_ORDER_ID", "")
endpoint := "https://api.smspva.com/activation/cancelorder/" + url.PathEscape(orderid) + ""
request, err := http.NewRequest("PUT", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_ORDER_ID");
var url = "https://api.smspva.com/activation/cancelorder/" + Uri.EscapeDataString(orderid) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("PUT"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_ORDER_ID", null);
String url = "https://api.smspva.com/activation/cancelorder/" + segment(orderid) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("PUT", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 405 | Parámetros no válidos |
| 406 | El ID del pedido no es válido o no se encontró. |
| 411 | Acceso limitado por karma bajo o exceso de solicitudes. |
| 501 | El servidor no pudo procesar la solicitud. |
| 503 | El servidor está sobrecargado. Inténtalo más tarde. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.orderId`** | integer | ID del pedido |
HTTP 405
Parámetros no válidos
**Respuesta ilustrativa**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 406
El ID del pedido no es válido o no se encontró.
**Respuesta ilustrativa**
```json
{
"statusCode": 406,
"error": {
"type": "ORDER_NOT_FOUND",
"description": "Order not found."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 411
Acceso limitado por karma bajo o exceso de solicitudes.
**Respuesta ilustrativa**
```json
{
"statusCode": 411,
"error": {
"type": "ACCESS_LIMITED",
"description": "Access is temporary limited."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 501
El servidor no pudo procesar la solicitud.
**Respuesta ilustrativa**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_BUSY",
"description": "Server failed to process request."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 503
El servidor está sobrecargado. Inténtalo más tarde.
**Respuesta ilustrativa**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Borrar SMS (/es/docs/api/clear-sms)
PUT{"https://api.smspva.com/activation/clearsms/{orderid}"}
**Esta solicitud puede modificar un pedido o generar cargos.** Los ejemplos no la repiten automáticamente. Leer un SMS recién recibido puede generar el cobro, aunque el método use GET.
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`orderid`** | path | integer | Sí | ID del pedido |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Borra el SMS actual para recibir otro en el mismo pedido. Conserva el **`orderExpireIn`** devuelto. HTTP **404** con **`NO_SMS_TO_CLEAN`** no confirma que se haya borrado un SMS.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
- **`SMSPVA_ORDER_ID`**: **`orderid`** (obligatorio).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_ORDER_ID:?Set SMSPVA_ORDER_ID to your orderid}"
curl --fail-with-body --max-time 30 --request PUT \
--url "https://api.smspva.com/activation/clearsms/${SMSPVA_ORDER_ID}" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/clearsms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/clearsms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_ORDER_ID"]
url = "https://api.smspva.com/activation/clearsms/" + quote(orderid, safe="") + ""
request = Request(url, method="PUT", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'PUT',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_ORDER_ID", "")
endpoint := "https://api.smspva.com/activation/clearsms/" + url.PathEscape(orderid) + ""
request, err := http.NewRequest("PUT", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_ORDER_ID");
var url = "https://api.smspva.com/activation/clearsms/" + Uri.EscapeDataString(orderid) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("PUT"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_ORDER_ID", null);
String url = "https://api.smspva.com/activation/clearsms/" + segment(orderid) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("PUT", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 404 | No se ha recibido un SMS, o hay uno pendiente de pago. |
| 405 | Parámetros no válidos |
| 406 | No se encontró el pedido. |
| 501 | El servidor no pudo procesar la solicitud. |
| 503 | No se ha recibido un SMS, o hay uno pendiente de pago. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456,
"orderExpireIn": 599
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.orderId`** | integer | ID del pedido |
| **`data.orderExpireIn`** | integer | Tiempo hasta el vencimiento, en segundos |
HTTP 404
No se ha recibido un SMS, o hay uno pendiente de pago.
**Respuesta ilustrativa**
```json
{
"statusCode": 404,
"error": {
"type": "NO_SMS_TO_CLEAN",
"description": "SMS not yet received or paid."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 405
Parámetros no válidos
**Respuesta ilustrativa**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 406
No se encontró el pedido.
**Respuesta ilustrativa**
```json
{
"statusCode": 406,
"error": {
"type": "ORDER_NOT_FOUND",
"description": "Order not found."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 501
El servidor no pudo procesar la solicitud.
**Respuesta ilustrativa**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_FAIL",
"description": "Server failed to process request"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Datos de respuesta |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 503
No se ha recibido un SMS, o hay uno pendiente de pago.
**Respuesta ilustrativa**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Tasas de conversión (/es/docs/api/conversions)
GET{"https://api.smspva.com/activation/conversions/{service}"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`service`** | path | string | Sí | Código de servicio |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Compara la probabilidad de recibir un SMS de un servicio en cada país. Envía su código en **`service`** para obtener las tasas por país. Son indicadores de calidad; no garantizan la recepción de un SMS concreto.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/conversions/opt1" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const service = process.env.SMSPVA_SERVICE ?? "opt1";
const url = "https://api.smspva.com/activation/conversions/" + encodeURIComponent(service) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const service = process.env.SMSPVA_SERVICE ?? "opt1";
const url = "https://api.smspva.com/activation/conversions/" + encodeURIComponent(service) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
service = os.environ.get("SMSPVA_SERVICE", "opt1")
url = "https://api.smspva.com/activation/conversions/" + quote(service, safe="") + ""
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
service := env("SMSPVA_SERVICE", "opt1")
endpoint := "https://api.smspva.com/activation/conversions/" + url.PathEscape(service) + ""
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt1";
var url = "https://api.smspva.com/activation/conversions/" + Uri.EscapeDataString(service) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String service = env("SMSPVA_SERVICE", "opt1");
String url = "https://api.smspva.com/activation/conversions/" + segment(service) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 400 | No se ha recibido la clave API. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"service": "opt1",
"conversions": {
"UA": 3,
"KZ": 2,
"RU": 3
}
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.service`** | string | Código de servicio |
| **`data.conversions`** | object | Tasas de conversión por país |
| **`data.conversions.*`** | integer | Indicador de calidad de 0 a 3; 3 es la mejor calidad. |
HTTP 400
No se ha recibido la clave API.
**Respuesta ilustrativa**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Disponibilidad de todos los números (/es/docs/api/countnumbers)
GET{"https://api.smspva.com/activation/countnumbers"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
Sin parámetros de ruta o consulta. No requiere cuerpo.
## Cómo usar este método [#cómo-usar-este-método]
Consulta los números disponibles por país, operador y servicio. Para un país concreto, usa [Disponibilidad por país](/es/docs/api/country-countnumbers). Compara el coste en [Todos los precios](/es/docs/api/all-service-prices).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/countnumbers" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/countnumbers";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/countnumbers";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/countnumbers"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/countnumbers"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/countnumbers";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/countnumbers";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 402 | Se ha superado el límite de solicitudes. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": [
{
"operator": "Primetel_CY",
"country": "CY",
"services": [
{
"service": "opt0",
"total": 12
}
]
}
]
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | array<object> | Datos de respuesta |
| **`data[].operator`** | string | Operador |
| **`data[].country`** | string | País |
| **`data[].services`** | array<object> | |
| **`data[].services[].service`** | string | Servicio |
| **`data[].services[].total`** | integer | Cantidad de números |
HTTP 402
Se ha superado el límite de solicitudes.
**Respuesta ilustrativa**
```json
{
"statusCode": 402,
"error": {
"type": "RATELIMIT_EXCEED",
"description": "Rate limit exceeded."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Disponibilidad por país (/es/docs/api/country-countnumbers)
GET{"https://api.smspva.com/activation/countnumbers/{country}"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | Sí | Código de país de dos caracteres en mayúsculas, en el formato ISO 3166-2 indicado por la API. [Lista de países](/es/docs/reference-data) |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Envía **`country`** para consultar la disponibilidad por operador y servicio. Elige el código en la [lista de países](/es/docs/reference-data) y compara los [precios por operador](/es/docs/api/country-operator-prices) antes de pedir un número.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/countnumbers/UK" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/countnumbers/" + encodeURIComponent(country) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/countnumbers/" + encodeURIComponent(country) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "UK")
url = "https://api.smspva.com/activation/countnumbers/" + quote(country, safe="") + ""
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "UK")
endpoint := "https://api.smspva.com/activation/countnumbers/" + url.PathEscape(country) + ""
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "UK";
var url = "https://api.smspva.com/activation/countnumbers/" + Uri.EscapeDataString(country) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "UK");
String url = "https://api.smspva.com/activation/countnumbers/" + segment(country) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": [
{
"operator": "Primetel_CY",
"country": "CY",
"services": [
{
"service": "opt0",
"total": 12
}
]
}
]
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | array<object> | Datos de respuesta |
| **`data[].operator`** | string | Operador |
| **`data[].country`** | string | País |
| **`data[].services`** | array<object> | |
| **`data[].services[].service`** | string | Servicio |
| **`data[].services[].total`** | integer | Cantidad de números |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Precios por país y operador (/es/docs/api/country-operator-prices)
GET{"https://api.smspva.com/activation/serviceprice/{country}"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | Sí | Código de país |
| **`voice`** | query | integer | No | Tipo: 0 SMS, 1 identificación de llamada, 2 voz. Valor predeterminado: 0. (**`enum: [0,1,2]`**; **`default: 0`**) |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Compara los precios de los servicios y de sus operadores en un **`country`**. Comprueba la [disponibilidad](/es/docs/api/country-countnumbers) y los [códigos de operador](/es/docs/api/operators) antes de solicitar un número.
La lista puede incluir operadores de SMSPVA y de proveedores externos, como **`DonorAlpha_UK`**. Ambos códigos se usan del mismo modo. Los números externos pueden ser menos fiables que las SIM reales de SMSPVA. Un recuento de **`9999`** indica que la cantidad exacta se desconoce; la disponibilidad puede ser prácticamente ilimitada.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/serviceprice/UK?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/serviceprice/" + encodeURIComponent(country) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/serviceprice/" + encodeURIComponent(country) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "UK")
url = "https://api.smspva.com/activation/serviceprice/" + quote(country, safe="") + "" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "UK")
endpoint := "https://api.smspva.com/activation/serviceprice/" + url.PathEscape(country) + "" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "UK";
var url = "https://api.smspva.com/activation/serviceprice/" + Uri.EscapeDataString(country) + "" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "UK");
String url = "https://api.smspva.com/activation/serviceprice/" + segment(country) + "" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 400 | No se ha recibido la clave API. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": [
{
"s": "opt0",
"sd": "myopinions & erewards",
"c": "UK",
"p": "0.58",
"po": {
"Hutchison_UK": "0.58",
"ASDA_UK": "0.58",
"Vodafone_UK": "0.65"
}
}
]
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | array<object> | Datos de respuesta |
| **`data[].s`** | string | Código de servicio |
| **`data[].sd`** | string | Descripción del servicio |
| **`data[].c`** | string | Código de país |
| **`data[].p`** | string | Precio base del servicio |
| **`data[].po`** | object | Precios de este servicio por nombre de operador |
| **`data[].po.*`** | string | Precio del operador |
HTTP 400
No se ha recibido la clave API.
**Respuesta ilustrativa**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Configuración de mensajes (/es/docs/api/country-service-settings)
GET{"https://api.smspva.com/activation/countryservicesettings"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
Sin parámetros de ruta o consulta. No requiere cuerpo.
## Cómo usar este método [#cómo-usar-este-método]
Comprueba qué tipos de mensaje permite la combinación de **`country`**, **`service`** y **`operator`**. Envía la cabecera **`apikey`**; no se necesitan parámetros de ruta ni de consulta. La respuesta incluye todas las reglas ordenadas por ID ascendente, aunque no muestra los IDs.
Cada condición no vacía debe coincidir; una cadena vacía acepta cualquier valor. Tiene prioridad la regla coincidente con más condiciones no vacías. Por ejemplo, una regla de país y servicio sustituye a una regla solo de país; añadir el operador la hace aún más específica. Usa juntos los tres indicadores de esa regla: **`sms`**, **`caller`** y **`voice`** emplean **1** para permitido y **0** para desactivado.
Si ninguna regla coincide, se permiten los tres tipos. Un array **`data`** vacío es una respuesta correcta sin reglas configuradas. Estos permisos no garantizan números disponibles.
El parámetro de consulta **`voice`** tiene otro significado al consultar precios o pedir números: **0** SMS, **1** identificación de llamada, **2** voz. Usa el mismo tipo al [comparar precios](/es/docs/api/service-price) y al pedir el número. Comprueba la [disponibilidad](/es/docs/api/country-countnumbers) por separado.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/countryservicesettings" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/countryservicesettings";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/countryservicesettings";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/countryservicesettings"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/countryservicesettings"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/countryservicesettings";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/countryservicesettings";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Reglas de tipos de mensaje. Una lista vacía es una respuesta correcta. |
| 400 | Falta la cabecera **`apikey`**, está vacía o tiene menos de 30 caracteres. |
| 401 | No se encontró una cuenta para esa clave API. |
| 402 | Se ha superado el límite de solicitudes. Esta API devuelve HTTP 402 para este error. |
| 403 | La cuenta está bloqueada. |
| 500 | Error interno. Si los detalles están habilitados, la descripción puede incluir la excepción. |
HTTP 200
Reglas de tipos de mensaje. Una lista vacía es una respuesta correcta.
**Reglas de servicio y reglas por país**
```json
{
"statusCode": 200,
"data": [
{
"country": "",
"service": "opt20",
"operator": "",
"voice": 0,
"caller": 0,
"sms": 1
},
{
"country": "FR",
"service": "opt20",
"operator": "",
"voice": 1,
"caller": 0,
"sms": 1
}
]
}
```
**Sin reglas configuradas**
```json
{
"statusCode": 200,
"data": []
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [200]`**) |
| **`data`** | array<object> | |
| **`data[].country`** | string | País al que se aplica; vacío acepta cualquier país. |
| **`data[].service`** | string | Servicio al que se aplica; vacío acepta cualquier servicio. |
| **`data[].operator`** | string | Operador al que se aplica; vacío acepta cualquier operador. |
| **`data[].voice`** | integer | Voz: 1 permitido, 0 desactivado. (**`enum: [0,1]`**) |
| **`data[].caller`** | integer | Identificación de llamada: 1 permitido, 0 desactivado. (**`enum: [0,1]`**) |
| **`data[].sms`** | integer | SMS: 1 permitido, 0 desactivado. (**`enum: [0,1]`**) |
HTTP 400
Falta la cabecera **`apikey`**, está vacía o tiene menos de 30 caracteres.
**Respuesta ilustrativa**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [400]`**) |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 401
No se encontró una cuenta para esa clave API.
**Respuesta ilustrativa**
```json
{
"statusCode": 401,
"error": {
"type": "USER_NOT_FOUND",
"description": "Not found"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [401]`**) |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 402
Se ha superado el límite de solicitudes. Esta API devuelve HTTP 402 para este error.
**Respuesta ilustrativa**
```json
{
"statusCode": 402,
"error": {
"type": "RATELIMIT_EXCEED",
"description": "Request ratelimit exeeded"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [402]`**) |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 403
La cuenta está bloqueada.
**Respuesta ilustrativa**
```json
{
"statusCode": 403,
"error": {
"type": "USER_BANNED",
"description": "User banned"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [403]`**) |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 500
Error interno. Si los detalles están habilitados, la descripción puede incluir la excepción.
**Respuesta ilustrativa**
```json
{
"statusCode": 500,
"error": {
"type": "SERVER_ERROR",
"description": "An internal error has occurred while processing your request."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [500]`**) |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Obtener número por operador (/es/docs/api/get-number-by-operator)
GET{"https://api.smspva.com/activation/number/{country}/{service}/{operator}"}
**Esta solicitud puede modificar un pedido o generar cargos.** Los ejemplos no la repiten automáticamente. Leer un SMS recién recibido puede generar el cobro, aunque el método use GET.
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | Sí | Código de país de dos caracteres en mayúsculas, en el formato ISO 3166-2 indicado por la API. [Lista de países](/es/docs/reference-data) |
| **`service`** | path | string | Sí | Código del servicio. [Lista de servicios](/es/docs/reference-data) |
| **`operator`** | path | string | Sí | Código de operador; se admiten operadores de SMSPVA y externos. |
| **`voice`** | query | integer | No | Tipo: 0 SMS, 1 identificación de llamada, 2 voz. Valor predeterminado: 0. (**`enum: [0,1,2]`**; **`default: 0`**) |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Solicita un número de un **`operator`** concreto para el **`country`** y el **`service`** elegidos. Se aceptan operadores de SMSPVA y externos.
Elige códigos en las [listas](/es/docs/reference-data). Antes de solicitar el número, consulta [precios](/es/docs/api/service-price), [disponibilidad](/es/docs/api/country-countnumbers) y [tipos de mensaje permitidos](/es/docs/api/country-service-settings). También puedes comparar [operadores](/es/docs/api/country-operator-prices) y [países](/es/docs/api/service-prices).
Guarda **`data.orderId`** para [Recibir SMS](/es/docs/api/receive-sms) y gestionar el pedido. Calcula su vencimiento con **`data.orderExpireIn`**. Si la solicitud agota el tiempo de espera, revisa [Pedidos actuales](/es/docs/api/orders) antes de pedir otro número: el primero puede haberse creado.
Obtén los códigos **`operator`** en [Operadores](/es/docs/api/operators). Los operadores externos, como **`DonorAlpha_UK`**, usan el mismo formato de solicitud, pero sus números pueden ser menos fiables que las SIM reales de SMSPVA.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/number/BD/opt20/Grameenphone_BD?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const operator = process.env.SMSPVA_OPERATOR ?? "Grameenphone_BD";
const url = "https://api.smspva.com/activation/number/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "/" + encodeURIComponent(operator) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const operator = process.env.SMSPVA_OPERATOR ?? "Grameenphone_BD";
const url = "https://api.smspva.com/activation/number/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "/" + encodeURIComponent(operator) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "BD")
service = os.environ.get("SMSPVA_SERVICE", "opt20")
operator = os.environ.get("SMSPVA_OPERATOR", "Grameenphone_BD")
url = "https://api.smspva.com/activation/number/" + quote(country, safe="") + "/" + quote(service, safe="") + "/" + quote(operator, safe="") + "" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "BD")
service := env("SMSPVA_SERVICE", "opt20")
operator := env("SMSPVA_OPERATOR", "Grameenphone_BD")
endpoint := "https://api.smspva.com/activation/number/" + url.PathEscape(country) + "/" + url.PathEscape(service) + "/" + url.PathEscape(operator) + "" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "BD";
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt20";
var operator = Environment.GetEnvironmentVariable("SMSPVA_OPERATOR") ?? "Grameenphone_BD";
var url = "https://api.smspva.com/activation/number/" + Uri.EscapeDataString(country) + "/" + Uri.EscapeDataString(service) + "/" + Uri.EscapeDataString(operator) + "" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "BD");
String service = env("SMSPVA_SERVICE", "opt20");
String operator = env("SMSPVA_OPERATOR", "Grameenphone_BD");
String url = "https://api.smspva.com/activation/number/" + segment(country) + "/" + segment(service) + "/" + segment(operator) + "" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 405 | Parámetros no válidos |
| 407 | El saldo no alcanza para recibir SMS del país y servicio elegidos. |
| 411 | Acceso limitado por karma bajo o exceso de solicitudes. |
| 500 | No se pudo obtener el número. |
| 501 | No se encontró el número. |
| 502 | No se encontró el número. |
| 503 | El servidor está sobrecargado. Inténtalo más tarde. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456,
"phoneNumber": 9876544321,
"countryCode": "BD",
"orderExpireIn": 600
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.orderId`** | integer | ID del pedido |
| **`data.phoneNumber`** | integer | Número sin prefijo de país |
| **`data.countryCode`** | string | Código de país según ITU-T E.123 y E.164. [Lista de países](/es/docs/reference-data) |
| **`data.orderExpireIn`** | integer | Tiempo hasta el vencimiento, en segundos |
HTTP 405
Parámetros no válidos
**Respuesta ilustrativa**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 407
El saldo no alcanza para recibir SMS del país y servicio elegidos.
HTTP 411
Acceso limitado por karma bajo o exceso de solicitudes.
HTTP 500
No se pudo obtener el número.
HTTP 501
No se encontró el número.
HTTP 502
No se encontró el número.
HTTP 503
El servidor está sobrecargado. Inténtalo más tarde.
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Obtener número (/es/docs/api/get-number)
GET{"https://api.smspva.com/activation/number/{country}/{service}"}
**Esta solicitud puede modificar un pedido o generar cargos.** Los ejemplos no la repiten automáticamente. Leer un SMS recién recibido puede generar el cobro, aunque el método use GET.
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | Sí | Código de país de dos caracteres en mayúsculas, en el formato ISO 3166-2 indicado por la API. [Lista de países](/es/docs/reference-data) |
| **`service`** | path | string | Sí | Código del servicio. [Lista de servicios](/es/docs/reference-data) |
| **`voice`** | query | integer | No | Tipo: 0 SMS, 1 identificación de llamada, 2 voz. Valor predeterminado: 0. (**`enum: [0,1,2]`**; **`default: 0`**) |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Solicita un número para el **`country`** y el **`service`** elegidos.
Elige códigos en las [listas](/es/docs/reference-data). Antes de solicitar el número, consulta [precios](/es/docs/api/service-price), [disponibilidad](/es/docs/api/country-countnumbers) y [tipos de mensaje permitidos](/es/docs/api/country-service-settings). También puedes comparar [operadores](/es/docs/api/country-operator-prices) y [países](/es/docs/api/service-prices).
Guarda **`data.orderId`** para [Recibir SMS](/es/docs/api/receive-sms) y gestionar el pedido. Calcula su vencimiento con **`data.orderExpireIn`**. Si la solicitud agota el tiempo de espera, revisa [Pedidos actuales](/es/docs/api/orders) antes de pedir otro número: el primero puede haberse creado.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/number/BD/opt20?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const url = "https://api.smspva.com/activation/number/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const url = "https://api.smspva.com/activation/number/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "BD")
service = os.environ.get("SMSPVA_SERVICE", "opt20")
url = "https://api.smspva.com/activation/number/" + quote(country, safe="") + "/" + quote(service, safe="") + "" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "BD")
service := env("SMSPVA_SERVICE", "opt20")
endpoint := "https://api.smspva.com/activation/number/" + url.PathEscape(country) + "/" + url.PathEscape(service) + "" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "BD";
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt20";
var url = "https://api.smspva.com/activation/number/" + Uri.EscapeDataString(country) + "/" + Uri.EscapeDataString(service) + "" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "BD");
String service = env("SMSPVA_SERVICE", "opt20");
String url = "https://api.smspva.com/activation/number/" + segment(country) + "/" + segment(service) + "" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 405 | Parámetros no válidos |
| 407 | El saldo no alcanza para recibir SMS del país y servicio elegidos. |
| 411 | Acceso limitado por karma bajo o exceso de solicitudes. |
| 500 | No se pudo obtener el número. |
| 501 | No se encontró el número. |
| 502 | No se encontró el número. |
| 503 | El servidor está sobrecargado. Inténtalo más tarde. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456,
"phoneNumber": 9876544321,
"countryCode": "BD",
"orderExpireIn": 600
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.orderId`** | integer | ID del pedido |
| **`data.phoneNumber`** | integer | Número sin prefijo de país |
| **`data.countryCode`** | string | Código de país según ITU-T E.123 y E.164. [Lista de países](/es/docs/reference-data) |
| **`data.orderExpireIn`** | integer | Tiempo hasta el vencimiento, en segundos |
HTTP 405
Parámetros no válidos
**Respuesta ilustrativa**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 407
El saldo no alcanza para recibir SMS del país y servicio elegidos.
**Respuesta ilustrativa**
```json
{
"statusCode": 407,
"error": {
"type": "LOW_BALANCE",
"description": "Low balance."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 411
Acceso limitado por karma bajo o exceso de solicitudes.
**Respuesta ilustrativa**
```json
{
"statusCode": 411,
"error": {
"type": "ACCESS_LIMITED",
"description": "Access is temporary limited."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 500
No se pudo obtener el número.
**Respuesta ilustrativa**
```json
{
"statusCode": 500,
"error": {
"type": "NUMBER_FETCH_FAIL",
"description": "Failed to fetch number"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 501
No se encontró el número.
**Respuesta ilustrativa**
```json
{
"statusCode": 501,
"error": {
"type": "PRICE_FETCH_FAIL",
"description": "Failed to fetch price"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Failed to fetch price |
HTTP 502
No se encontró el número.
**Respuesta ilustrativa**
```json
{
"statusCode": 502,
"error": {
"type": "NUMBER_NOT_FOUND",
"description": "Number not found."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 503
El servidor está sobrecargado. Inténtalo más tarde.
**Respuesta ilustrativa**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Activation V2 (/es/docs/api)
URL base: **https://api.smspva.com** · **`apikey`** header.
Empieza con la [guía de activación](/es/docs/activation-workflow) para pedir un número y recibir el resultado. La referencia de cada método explica sus parámetros y respuestas, incluida la espera HTTP **202**.
## Cuenta [#cuenta]
| Método | Ruta | Descripción |
| --- | --- | --- |
| GET | **`/activation/balance`** | [Consultar saldo](/es/docs/api/balance) |
| GET | **`/activation/userinfo`** | [Información de usuario](/es/docs/api/userinfo) |
## Datos de referencia [#datos-de-referencia]
| Método | Ruta | Descripción |
| --- | --- | --- |
| GET | **`/activation/operators/{country}`** | [Operadores](/es/docs/api/operators) |
| GET | **`/activation/conversions/{service}`** | [Tasas de conversión](/es/docs/api/conversions) |
| GET | **`/activation/countryservicesettings`** | [Configuración de mensajes](/es/docs/api/country-service-settings) |
## Disponibilidad [#disponibilidad]
| Método | Ruta | Descripción |
| --- | --- | --- |
| GET | **`/activation/countnumbers`** | [Disponibilidad de todos los números](/es/docs/api/countnumbers) |
| GET | **`/activation/countnumbers/{country}`** | [Disponibilidad por país](/es/docs/api/country-countnumbers) |
## Precios [#precios]
| Método | Ruta | Descripción |
| --- | --- | --- |
| GET | **`/activation/serviceprice/{country}/{service}`** | [Precio del servicio](/es/docs/api/service-price) |
| GET | **`/activation/serviceprice/{country}`** | [Precios por país y operador](/es/docs/api/country-operator-prices) |
| GET | **`/activation/serviceprices/{service}`** | [Precios del servicio por país](/es/docs/api/service-prices) |
| GET | **`/activation/servicesprices`** | [Todos los precios](/es/docs/api/all-service-prices) |
## Pedidos y resultados [#pedidos-y-resultados]
| Método | Ruta | Descripción |
| --- | --- | --- |
| GET | **`/activation/number/{country}/{service}`** | [Obtener número](/es/docs/api/get-number) |
| GET | **`/activation/number/{country}/{service}/{operator}`** | [Obtener número por operador](/es/docs/api/get-number-by-operator) |
| GET | **`/activation/sms/{orderid}`** | [Recibir SMS](/es/docs/api/receive-sms) |
| GET | **`/activation/orders`** | [Pedidos actuales](/es/docs/api/orders) |
| GET | **`/activation/numberstatus/{number}/{service}`** | [Estado del número](/es/docs/api/number-status) |
## Gestionar pedidos [#gestionar-pedidos]
| Método | Ruta | Descripción |
| --- | --- | --- |
| PUT | **`/activation/clearsms/{orderid}`** | [Borrar SMS](/es/docs/api/clear-sms) |
| PUT | **`/activation/stopsms/{orderid}`** | [Detener SMS](/es/docs/api/stop-sms) |
| PUT | **`/activation/cancelorder/{orderid}`** | [Cancelar pedido](/es/docs/api/cancel-order) |
| PUT | **`/activation/blocknumber/{orderid}`** | [Bloquear número](/es/docs/api/block-number) |
[Descargar OpenAPI](/openapi/activation-v2.json)
# Estado del número (/es/docs/api/number-status)
GET{"https://api.smspva.com/activation/numberstatus/{number}/{service}"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`number`** | path | string | Sí | Número sin prefijo telefónico del país. (**`pattern: "^[0-9]{5,}$"`**) |
| **`service`** | path | string | Sí | Código de servicio. Consulta los códigos en servicesprices. |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Comprueba si un número que ya has usado puede seguir recibiendo SMS del mismo **`service`**. La consulta solo sirve si antes recibiste SMS de ese servicio en ese número. Envía **`number`** sin el prefijo telefónico del país.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
- **`SMSPVA_NUMBER`**: number (obligatorio).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_NUMBER:?Set SMSPVA_NUMBER to your number}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/numberstatus/${SMSPVA_NUMBER}/opt0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const number = required("SMSPVA_NUMBER");
const service = process.env.SMSPVA_SERVICE ?? "opt0";
const url = "https://api.smspva.com/activation/numberstatus/" + encodeURIComponent(number) + "/" + encodeURIComponent(service) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const number = required("SMSPVA_NUMBER");
const service = process.env.SMSPVA_SERVICE ?? "opt0";
const url = "https://api.smspva.com/activation/numberstatus/" + encodeURIComponent(number) + "/" + encodeURIComponent(service) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
number = os.environ["SMSPVA_NUMBER"]
service = os.environ.get("SMSPVA_SERVICE", "opt0")
url = "https://api.smspva.com/activation/numberstatus/" + quote(number, safe="") + "/" + quote(service, safe="") + ""
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
number := env("SMSPVA_NUMBER", "")
service := env("SMSPVA_SERVICE", "opt0")
endpoint := "https://api.smspva.com/activation/numberstatus/" + url.PathEscape(number) + "/" + url.PathEscape(service) + ""
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var number = Required("SMSPVA_NUMBER");
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt0";
var url = "https://api.smspva.com/activation/numberstatus/" + Uri.EscapeDataString(number) + "/" + Uri.EscapeDataString(service) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String number = env("SMSPVA_NUMBER", null);
String service = env("SMSPVA_SERVICE", "opt0");
String url = "https://api.smspva.com/activation/numberstatus/" + segment(number) + "/" + segment(service) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 405 | Formato de número no válido |
| 406 | El ID del pedido no es válido o no se encontró. |
| 500 | Error interno. La descripción puede incluir información de diagnóstico. |
| 501 | El servidor no pudo procesar la solicitud. |
| 502 | No se encontró el número. |
| 503 | El servidor está sobrecargado. Inténtalo más tarde. |
| 504 | **`av2.resp.504.desc`**: la fuente no incluye una descripción desarrollada para esta respuesta. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"number": "98765432",
"orderId": 123456,
"countryCode": "+7"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.number`** | string | Número sin prefijo telefónico del país. |
| **`data.orderId`** | integer | ID de tu pedido anterior para ese número y servicio. |
| **`data.countryCode`** | string | Prefijo telefónico del país. |
HTTP 405
Formato de número no válido
**Respuesta ilustrativa**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_NUMBER_FORMAT",
"description": "Number should be integer with more than 5 digits"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Datos de respuesta |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 406
El ID del pedido no es válido o no se encontró.
**Respuesta ilustrativa**
```json
{
"statusCode": 406,
"error": {
"type": "ORDER_NOT_FOUND",
"description": "Order not found."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 500
Error interno. La descripción puede incluir información de diagnóstico.
**Respuesta ilustrativa**
```json
{
"statusCode": 500,
"error": {
"type": "SERVER_ERROR",
"description": "An internal error has occurred while processing your request."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 501
El servidor no pudo procesar la solicitud.
HTTP 502
No se encontró el número.
HTTP 503
El servidor está sobrecargado. Inténtalo más tarde.
HTTP 504
**`av2.resp.504.desc`**: la fuente no incluye una descripción desarrollada para esta respuesta.
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Operadores (/es/docs/api/operators)
GET{"https://api.smspva.com/activation/operators/{country}"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | Sí | Código de país |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Consulta los operadores disponibles en el país elegido con **`country`**. Usa el código devuelto para solicitar un número de un operador concreto.
La lista puede incluir operadores de SMSPVA y de proveedores externos, como **`DonorAlpha_UK`**. Ambos códigos se usan del mismo modo. Los números externos pueden ser menos fiables que las SIM reales de SMSPVA. Un recuento de **`9999`** indica que la cantidad exacta se desconoce; la disponibilidad puede ser prácticamente ilimitada.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/operators/UK" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/operators/" + encodeURIComponent(country) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/operators/" + encodeURIComponent(country) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "UK")
url = "https://api.smspva.com/activation/operators/" + quote(country, safe="") + ""
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "UK")
endpoint := "https://api.smspva.com/activation/operators/" + url.PathEscape(country) + ""
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "UK";
var url = "https://api.smspva.com/activation/operators/" + Uri.EscapeDataString(country) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "UK");
String url = "https://api.smspva.com/activation/operators/" + segment(country) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 400 | No se ha recibido la clave API. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"country": "UK",
"operators": [
"DonorAlpha_UK"
]
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.country`** | string | Código de país |
| **`data.operators`** | array<string> | Lista de operadores disponibles |
HTTP 400
No se ha recibido la clave API.
**Respuesta ilustrativa**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Pedidos actuales (/es/docs/api/orders)
GET{"https://api.smspva.com/activation/orders"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
Sin parámetros de ruta o consulta. No requiere cuerpo.
## Cómo usar este método [#cómo-usar-este-método]
Consulta tus pedidos de activación actuales. Usa el **`orderId`** devuelto para [Recibir SMS](/es/docs/api/receive-sms) y gestionar cada pedido.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/orders" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/orders";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/orders";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/orders"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/orders"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/orders";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/orders";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 501 | El servidor no pudo procesar la solicitud. |
| 503 | El servidor está sobrecargado. Inténtalo más tarde. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"orders": [
{
"orderId": 123456,
"phoneNumber": 987654321,
"countryCode": "+7",
"orderExpireIn": 599,
"service": "opt0",
"country": "UK",
"status": "PENDING_SMS|SMS_READY|PENDING_PAYMENT",
"sms": {
"code": "1234",
"fullText": "Your service Activation code is 1234. Don't tell it anybody"
}
}
]
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.orders`** | array<object> | Datos de respuesta |
| **`data.orders[].orderId`** | integer | ID del pedido |
| **`data.orders[].phoneNumber`** | integer | Número sin prefijo de país |
| **`data.orders[].countryCode`** | string | Prefijo telefónico del país. |
| **`data.orders[].orderExpireIn`** | integer | Tiempo hasta el vencimiento, en segundos |
| **`data.orders[].service`** | string | Código de servicio [Lista de servicios](/es/docs/reference-data) |
| **`data.orders[].country`** | string | Código de país según ITU-T E.123 y E.164. [Lista de países](/es/docs/reference-data) |
| **`data.orders[].status`** | string | Estado del SMS. |
| **`data.orders[].sms`** | object | Estado del SMS. |
| **`data.orders[].sms.code`** | string | Código de activación recibido por SMS. |
| **`data.orders[].sms.fullText`** | string | Texto completo del SMS. |
HTTP 501
El servidor no pudo procesar la solicitud.
**Respuesta ilustrativa**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_FAIL",
"description": "Server failed to process request"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Datos de respuesta |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 503
El servidor está sobrecargado. Inténtalo más tarde.
**Respuesta ilustrativa**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Datos de respuesta |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Recibir SMS (/es/docs/api/receive-sms)
GET{"https://api.smspva.com/activation/sms/{orderid}"}
**Esta solicitud puede modificar un pedido o generar cargos.** Los ejemplos no la repiten automáticamente. Leer un SMS recién recibido puede generar el cobro, aunque el método use GET.
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
| **`partnerkey`** | header | string | No | Clave de socio opcional para referidos; se aplica solo al recibir un SMS correctamente. |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`orderid`** | path | integer | Sí | ID devuelto al solicitar el número |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Usa el **`orderId`** recibido al pedir el número o en [Pedidos actuales](/es/docs/api/orders). Este método también devuelve resultados de voz e identificación de llamada; el tipo ya se eligió con **`voice=0`**, **`voice=1`** o **`voice=2`**. Aquí no debes enviar **`voice`**.
El campo **`text`** del proveedor pasa a **`data.sms.code`** y **`sms`** pasa a **`data.sms.fullText`**, sin cambios. Por eso, **`code`** no siempre contiene un código numérico.
HTTP **202** con **`statusCode=202`** y **`error.type=SMS_NOT_YET_RECEIVED`** significa que el resultado sigue pendiente. Reconócelo antes de los errores generales y espera antes de consultar de nuevo. Se aplica a los tres tipos de mensaje. Consulta la [guía de espera](/es/docs/activation-workflow).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
- **`SMSPVA_ORDER_ID`**: **`orderid`** (obligatorio).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_ORDER_ID:?Set SMSPVA_ORDER_ID to your orderid}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/sms/${SMSPVA_ORDER_ID}" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/sms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (response.status === 202 && result.statusCode === 202 &&
result.error?.type === "SMS_NOT_YET_RECEIVED") {
console.log("Pending. Poll again later within the order lifetime.");
} else if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/sms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (response.status === 202 && result.statusCode === 202 &&
result.error?.type === "SMS_NOT_YET_RECEIVED") {
console.log("Pending. Poll again later within the order lifetime.");
} else if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_ORDER_ID"]
url = "https://api.smspva.com/activation/sms/" + quote(orderid, safe="") + ""
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if status == 202 and result.get("statusCode") == 202 and result.get("error", {}).get("type") == "SMS_NOT_YET_RECEIVED":
print("Pending. Poll again later within the order lifetime.")
elif not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status === 202 && ($result['statusCode'] ?? 0) === 202 &&
($result['error']['type'] ?? '') === 'SMS_NOT_YET_RECEIVED') {
echo "Pending. Poll again later within the order lifetime.\n";
} elseif ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_ORDER_ID", "")
endpoint := "https://api.smspva.com/activation/sms/" + url.PathEscape(orderid) + ""
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode == 202 && result.StatusCode == 202 {
var detail struct { Type string `json:"type"` }
if json.Unmarshal(result.Error, &detail) == nil && detail.Type == "SMS_NOT_YET_RECEIVED" {
fmt.Println("Pending. Poll again later within the order lifetime.")
return
}
}
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_ORDER_ID");
var url = "https://api.smspva.com/activation/sms/" + Uri.EscapeDataString(orderid) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if ((int)response.StatusCode == 202 && apiStatus == 202 && hasError &&
error.TryGetProperty("type", out var kind) && kind.GetString() == "SMS_NOT_YET_RECEIVED")
{
Console.WriteLine("Pending. Poll again later within the order lifetime.");
}
else if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_ORDER_ID", null);
String url = "https://api.smspva.com/activation/sms/" + segment(orderid) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 202) {
// Inspect SMS_NOT_YET_RECEIVED in the raw JSON body before scheduling another poll.
System.out.println("Pending response: " + response.body());
return;
}
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 202 | El resultado sigue pendiente. SMS, voz e identificación de llamada usan **`SMS_NOT_YET_RECEIVED`** y **`Waiting for SMS`** para indicar la espera. |
| 405 | Parámetros no válidos |
| 406 | El ID del pedido no es válido o no se encontró. |
| 407 | Se ha recibido el SMS, pero el saldo no alcanza para pagarlo. |
| 410 | El pedido está cerrado y ya no está disponible. |
| 411 | Acceso limitado por karma bajo o exceso de solicitudes. |
| 500 | No se pudo obtener el SMS. |
| 501 | El servidor no pudo procesar la solicitud. |
| 503 | El servidor está sobrecargado. Inténtalo más tarde. |
HTTP 200
Operación completada
**SMS (voice=0)**
```json
{
"statusCode": 200,
"data": {
"sms": {
"code": "123456",
"fullText": "Your verification code is 123456"
},
"orderId": 123456,
"orderExpireIn": 420
}
}
```
**Llamada de voz (voice=2)**
Ejemplo de voz. **`fullText`** contiene texto y un enlace a la grabación con el formato **`VOICE: ...; The file: ...`**.
El contenido de **`code`** depende del proveedor y no está confirmado; no siempre será un código numérico.
```json
{
"statusCode": 200,
"data": {
"sms": {
"code": "",
"fullText": "VOICE: Your code is 123456; The file: https://link.smspva.com/EXAMPLE_RECORD_ID"
},
"orderId": 123456,
"orderExpireIn": 420
}
}
```
**Voz: solo enlace (voice=2)**
Formato posible: **`fullText`** puede contener solo el enlace a la grabación. Esta variante no está confirmada; evita depender de un formato fijo.
**`code`** representa el valor **`text`** del proveedor, sin modificarlo.
```json
{
"statusCode": 200,
"data": {
"sms": {
"code": "",
"fullText": "https://link.smspva.com/EXAMPLE_RECORD_ID"
},
"orderId": 123456,
"orderExpireIn": 420
}
}
```
**Identificación de llamada (voice=1)**
La estructura JSON es la misma que para SMS. Los valores son marcadores: el formato exacto de identificación de llamada aún no está confirmado.
El proveedor puede devolver un código o número de llamada en **`code`**, y un mensaje en **`fullText`**. **`code`** no siempre es un código de verificación.
```json
{
"statusCode": 200,
"data": {
"sms": {
"code": "",
"fullText": ""
},
"orderId": 123456,
"orderExpireIn": 420
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.sms`** | object | Contenido del SMS recibido |
| **`data.sms.code`** | string | Campo text del proveedor, sin cambios. El contenido depende del tipo de mensaje y proveedor; no siempre es un código de verificación. |
| **`data.sms.fullText`** | string | Campo sms del proveedor, sin cambios. Puede incluir texto SMS, texto de voz y grabación, solo un enlace de grabación o identificación de llamada. |
| **`data.orderId`** | integer | ID del pedido |
| **`data.orderExpireIn`** | integer | Tiempo hasta el vencimiento, en segundos |
HTTP 202
El resultado sigue pendiente. SMS, voz e identificación de llamada usan **`SMS_NOT_YET_RECEIVED`** y **`Waiting for SMS`** para indicar la espera.
**Respuesta ilustrativa**
```json
{
"statusCode": 202,
"error": {
"type": "SMS_NOT_YET_RECEIVED",
"description": "Waiting for SMS"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 405
Parámetros no válidos
**Respuesta ilustrativa**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params, please re-check the specified data."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 406
El ID del pedido no es válido o no se encontró.
**Respuesta ilustrativa**
```json
{
"statusCode": 406,
"error": {
"type": "INVALID_ORDER_FORMAT",
"description": "Order should be integer."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 407
Se ha recibido el SMS, pero el saldo no alcanza para pagarlo.
**Respuesta ilustrativa**
```json
{
"statusCode": 407,
"error": {
"type": "LOW_BALANCE",
"description": "Low balance"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 410
El pedido está cerrado y ya no está disponible.
**Respuesta ilustrativa**
```json
{
"statusCode": 410,
"error": {
"type": "ORDER_CLOSED",
"description": "Order closed and unavailable"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 411
Acceso limitado por karma bajo o exceso de solicitudes.
**Respuesta ilustrativa**
```json
{
"statusCode": 411,
"error": {
"type": "ACCESS_LIMITED",
"description": "Access is temporary limited"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 500
No se pudo obtener el SMS.
**Respuesta ilustrativa**
```json
{
"statusCode": 500,
"error": {
"type": "SMS_FETCH_FAIL",
"description": "Failed to fetch SMS."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 501
El servidor no pudo procesar la solicitud.
**Respuesta ilustrativa**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_FAIL",
"description": "Server failed to process request"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 503
El servidor está sobrecargado. Inténtalo más tarde.
**Respuesta ilustrativa**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Precio del servicio (/es/docs/api/service-price)
GET{"https://api.smspva.com/activation/serviceprice/{country}/{service}"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | Sí | Código de país de dos caracteres en mayúsculas, en el formato ISO 3166-2 indicado por la API. [Lista de países](/es/docs/reference-data) |
| **`service`** | path | string | Sí | Código del servicio. [Lista de servicios](/es/docs/reference-data) |
| **`voice`** | query | integer | No | Tipo: 0 SMS, 1 identificación de llamada, 2 voz. Valor predeterminado: 0. (**`enum: [0,1,2]`**; **`default: 0`**) |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Consulta el precio de un **`country`** y un **`service`**, incluidos los precios de **`priceByOperators`**. Elige códigos en las [listas](/es/docs/reference-data), comprueba la [disponibilidad](/es/docs/api/country-countnumbers) o compara [otros países](/es/docs/api/service-prices).
La lista puede incluir operadores de SMSPVA y de proveedores externos, como **`DonorAlpha_UK`**. Ambos códigos se usan del mismo modo. Los números externos pueden ser menos fiables que las SIM reales de SMSPVA. Un recuento de **`9999`** indica que la cantidad exacta se desconoce; la disponibilidad puede ser prácticamente ilimitada.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/serviceprice/BD/opt0?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt0";
const url = "https://api.smspva.com/activation/serviceprice/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt0";
const url = "https://api.smspva.com/activation/serviceprice/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "BD")
service = os.environ.get("SMSPVA_SERVICE", "opt0")
url = "https://api.smspva.com/activation/serviceprice/" + quote(country, safe="") + "/" + quote(service, safe="") + "" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "BD")
service := env("SMSPVA_SERVICE", "opt0")
endpoint := "https://api.smspva.com/activation/serviceprice/" + url.PathEscape(country) + "/" + url.PathEscape(service) + "" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "BD";
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt0";
var url = "https://api.smspva.com/activation/serviceprice/" + Uri.EscapeDataString(country) + "/" + Uri.EscapeDataString(service) + "" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "BD");
String service = env("SMSPVA_SERVICE", "opt0");
String url = "https://api.smspva.com/activation/serviceprice/" + segment(country) + "/" + segment(service) + "" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 405 | country o service no es válido. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"service": "opt0",
"serviceDescription": "myopinions & erewards",
"country": "KZ",
"price": "2.34",
"priceByOperators": {
"Other_KZ": "0.39",
"Activ_KZ": "0.39"
}
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.service`** | string | Servicio |
| **`data.serviceDescription`** | string | Descripción del servicio. |
| **`data.country`** | string | País |
| **`data.price`** | string | Precio. |
| **`data.priceByOperators`** | object | Precios agrupados por operador. |
| **`data.priceByOperators.*`** | string | |
HTTP 405
country o service no es válido.
**Respuesta ilustrativa**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Precios del servicio por país (/es/docs/api/service-prices)
GET{"https://api.smspva.com/activation/serviceprices/{service}"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`service`** | path | string | Sí | Código del servicio. [Lista de servicios](/es/docs/reference-data) (**`pattern: "^opt[0-9]{1,8}$"`**) |
| **`voice`** | query | integer | No | Tipo: 0 SMS, 1 identificación de llamada, 2 voz. Valor predeterminado: 0. (**`enum: [0,1,2]`**; **`default: 0`**) |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Compara los precios y la disponibilidad de un **`service`** entre países y operadores. Usa los códigos elegidos en [Obtener número por operador](/es/docs/api/get-number-by-operator).
La lista puede incluir operadores de SMSPVA y de proveedores externos, como **`DonorAlpha_UK`**. Ambos códigos se usan del mismo modo. Los números externos pueden ser menos fiables que las SIM reales de SMSPVA. Un recuento de **`9999`** indica que la cantidad exacta se desconoce; la disponibilidad puede ser prácticamente ilimitada.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/serviceprices/opt20?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const url = "https://api.smspva.com/activation/serviceprices/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const url = "https://api.smspva.com/activation/serviceprices/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
service = os.environ.get("SMSPVA_SERVICE", "opt20")
url = "https://api.smspva.com/activation/serviceprices/" + quote(service, safe="") + "" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
service := env("SMSPVA_SERVICE", "opt20")
endpoint := "https://api.smspva.com/activation/serviceprices/" + url.PathEscape(service) + "" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt20";
var url = "https://api.smspva.com/activation/serviceprices/" + Uri.EscapeDataString(service) + "" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String service = env("SMSPVA_SERVICE", "opt20");
String url = "https://api.smspva.com/activation/serviceprices/" + segment(service) + "" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 405 | Parámetros no válidos |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"scode": "opt20",
"sname": "WhatsApp",
"clist": [
{
"ccode": "UK",
"cname": "United Kingdom",
"opers": [
{
"opcode": "DonorAlpha_UK",
"price": 0.65,
"count": 9999
}
]
}
]
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.scode`** | string | Código del servicio. |
| **`data.sname`** | string | Nombre del servicio. |
| **`data.clist`** | array<object> | Países y operadores disponibles para el servicio. |
| **`data.clist[].ccode`** | string | Código del país. |
| **`data.clist[].cname`** | string | Nombre del país. |
| **`data.clist[].opers`** | array<object> | |
| **`data.clist[].opers[].opcode`** | string | Código de un operador de SMSPVA o de un proveedor externo. |
| **`data.clist[].opers[].price`** | number | Precio del operador. (**`format: "float"`**) |
| **`data.clist[].opers[].count`** | integer | Números disponibles. Para proveedores externos, **`9999`** indica una cantidad exacta desconocida y disponibilidad posiblemente ilimitada. |
HTTP 405
Parámetros no válidos
**Respuesta ilustrativa**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Detener SMS (/es/docs/api/stop-sms)
PUT{"https://api.smspva.com/activation/stopsms/{orderid}"}
**Esta solicitud puede modificar un pedido o generar cargos.** Los ejemplos no la repiten automáticamente. Leer un SMS recién recibido puede generar el cobro, aunque el método use GET.
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`orderid`** | path | integer | Sí | ID del pedido |
No requiere cuerpo de solicitud.
## Cómo usar este método [#cómo-usar-este-método]
Detén la recepción de SMS de este **`orderid`**.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
- **`SMSPVA_ORDER_ID`**: **`orderid`** (obligatorio).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_ORDER_ID:?Set SMSPVA_ORDER_ID to your orderid}"
curl --fail-with-body --max-time 30 --request PUT \
--url "https://api.smspva.com/activation/stopsms/${SMSPVA_ORDER_ID}" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/stopsms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/stopsms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_ORDER_ID"]
url = "https://api.smspva.com/activation/stopsms/" + quote(orderid, safe="") + ""
request = Request(url, method="PUT", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'PUT',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_ORDER_ID", "")
endpoint := "https://api.smspva.com/activation/stopsms/" + url.PathEscape(orderid) + ""
request, err := http.NewRequest("PUT", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_ORDER_ID");
var url = "https://api.smspva.com/activation/stopsms/" + Uri.EscapeDataString(orderid) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("PUT"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_ORDER_ID", null);
String url = "https://api.smspva.com/activation/stopsms/" + segment(orderid) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("PUT", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 405 | Parámetros no válidos |
| 406 | El ID del pedido no es válido o no se encontró. |
| 411 | Acceso limitado por karma bajo o exceso de solicitudes. |
| 501 | El servidor no pudo procesar la solicitud. |
| 503 | El servidor está sobrecargado. Inténtalo más tarde. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.orderId`** | integer | ID del pedido |
HTTP 405
Parámetros no válidos
**Respuesta ilustrativa**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 406
El ID del pedido no es válido o no se encontró.
**Respuesta ilustrativa**
```json
{
"statusCode": 406,
"error": {
"type": "ORDER_NOT_FOUND",
"description": "Order not found."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 411
Acceso limitado por karma bajo o exceso de solicitudes.
**Respuesta ilustrativa**
```json
{
"statusCode": 411,
"error": {
"type": "ACCESS_LIMITED",
"description": "Access is temporary limited."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 501
El servidor no pudo procesar la solicitud.
**Respuesta ilustrativa**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_FAIL",
"description": "Server failed to process request."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
HTTP 503
El servidor está sobrecargado. Inténtalo más tarde.
**Respuesta ilustrativa**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`error`** | object | Detalles del error |
| **`error.type`** | string | Tipo de error |
| **`error.description`** | string | Descripción del error |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Información de usuario (/es/docs/api/userinfo)
GET{"https://api.smspva.com/activation/userinfo"}
## Autenticación [#autenticación]
| Nombre | Ubicación | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | Sí | Tu clave API |
## Parámetros [#parámetros]
Sin parámetros de ruta o consulta. No requiere cuerpo.
## Cómo usar este método [#cómo-usar-este-método]
Consulta el nombre de la cuenta, el saldo y el karma en una sola solicitud.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Requisitos y configuración del entorno](/es/docs/examples). cURL usa un shell POSIX. El ejemplo JavaScript también es válido en TypeScript sobre Node.js. Java utiliza el cliente estándar y muestra JSON sin analizar; usa la biblioteca JSON de tu aplicación.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/userinfo" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/userinfo";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/userinfo";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/userinfo"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/userinfo"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/userinfo";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/userinfo";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## Respuestas [#respuestas]
Los ejemplos muestran el formato de respuesta. Los precios, las cantidades y los datos de cuenta son orientativos; consulta la API para obtener valores actuales.
| HTTP | Descripción |
| --- | --- |
| 200 | Operación completada |
| 400 | Falta la cabecera **`apikey`**, está vacía o su longitud no es válida. |
HTTP 200
Operación completada
**Respuesta ilustrativa**
```json
{
"statusCode": 200,
"data": {
"balance": "10.50",
"name": "user123",
"karma": 100.5
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | Código de estado del resultado |
| **`data`** | object | Datos de respuesta |
| **`data.balance`** | string | Saldo |
| **`data.name`** | string | Nombre de la cuenta. |
| **`data.karma`** | number | Karma de la cuenta. (**`format: "float"`**) |
HTTP 400
Falta la cabecera **`apikey`**, está vacía o su longitud no es válida.
**Respuesta ilustrativa**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**Campos de respuesta**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`statusCode`** | integer | |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
## Guías relacionadas [#guías-relacionadas]
- [Activation V2](/es/docs/api)
- [Datos de referencia](/es/docs/reference-data)
- [Flujo de activación](/es/docs/activation-workflow)
- [Errores y límites](/es/docs/errors)
- [Descargar OpenAPI](/openapi/activation-v2.json)
Si falla la conexión al modificar un pedido, comprueba su estado antes de repetir.
# Mensajes del alias (/es/docs/email/alias-messages)
GET{"https://smspva.com/api/rent_email.php?method=get_mails_by_alias"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "get_mails_by_alias" | Método que se va a ejecutar. |
| **`orderid`** | query | integer | Sí | 123456 | ID de Create Order, Active Orders o Archived Orders, según el método que vayas a usar. |
| **`aliasid`** | query | integer | Sí | 88 | ID de un alias existente, tomado de aliases en Active Orders. **`orderid`** debe ser el ID del pedido padre. |
| **`t`** | query | integer | No | 50 | Número de resultados por página. |
| **`s`** | query | integer | No | 0 | Número de resultados que se omiten al paginar. |
| **`sq`** | query | string | No | "verification" | Texto de búsqueda. Codifícalo para enviarlo en la URL. |
## Cómo usar este método [#cómo-usar-este-método]
Lee los mensajes de un alias de Gmail existente. Obtén ambos IDs en [Pedidos activos](/es/docs/email/orders): **`orderid`** es el **ID del alquiler padre** y **`aliasid`** identifica el alias. Compra antes el [acceso al alias](/es/docs/email/buy-alias).
Usa **`t`**, **`s`** y **`sq`** como en [Mensajes](/es/docs/email/messages). Para leer el contenido completo, envía el **`orderid`** padre y el ID del mensaje como **`emailid`** a [Contenido del mensaje](/es/docs/email/message-body).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
- **`SMSPVA_EMAIL_ALIAS_ID`**: **`aliasid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
: "${SMSPVA_EMAIL_ALIAS_ID:?Set SMSPVA_EMAIL_ALIAS_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_mails_by_alias" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID" \
--data-urlencode "aliasid=$SMSPVA_EMAIL_ALIAS_ID" \
--data-urlencode "t=${SMSPVA_EMAIL_T:-50}" \
--data-urlencode "s=${SMSPVA_EMAIL_S:-0}" \
--data-urlencode "sq=${SMSPVA_EMAIL_SQ:-verification}"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const aliasid = required("SMSPVA_EMAIL_ALIAS_ID");
const t = process.env.SMSPVA_EMAIL_T ?? "50";
const s = process.env.SMSPVA_EMAIL_S ?? "0";
const sq = process.env.SMSPVA_EMAIL_SQ ?? "verification";
const query = new URLSearchParams({
"method": "get_mails_by_alias",
"orderid": orderid,
"aliasid": aliasid,
"t": t,
"s": s,
"sq": sq
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const aliasid = required("SMSPVA_EMAIL_ALIAS_ID");
const t = process.env.SMSPVA_EMAIL_T ?? "50";
const s = process.env.SMSPVA_EMAIL_S ?? "0";
const sq = process.env.SMSPVA_EMAIL_SQ ?? "verification";
const query = new URLSearchParams({
"method": "get_mails_by_alias",
"orderid": orderid,
"aliasid": aliasid,
"t": t,
"s": s,
"sq": sq
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
aliasid = os.environ["SMSPVA_EMAIL_ALIAS_ID"]
t = os.environ.get("SMSPVA_EMAIL_T", "50")
s = os.environ.get("SMSPVA_EMAIL_S", "0")
sq = os.environ.get("SMSPVA_EMAIL_SQ", "verification")
query = {
"method": "get_mails_by_alias",
"orderid": orderid,
"aliasid": aliasid,
"t": t,
"s": s,
"sq": sq
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_mails_by_alias',
'orderid' => $orderid,
'aliasid' => $aliasid,
't' => $t,
's' => $s,
'sq' => $sq
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
aliasid := env("SMSPVA_EMAIL_ALIAS_ID", "")
t := env("SMSPVA_EMAIL_T", "50")
s := env("SMSPVA_EMAIL_S", "0")
sq := env("SMSPVA_EMAIL_SQ", "verification")
query := url.Values{}
query.Set("method", "get_mails_by_alias")
query.Set("orderid", orderid)
query.Set("aliasid", aliasid)
query.Set("t", t)
query.Set("s", s)
query.Set("sq", sq)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var aliasid = Required("SMSPVA_EMAIL_ALIAS_ID");
var t = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_T") ?? "50";
var s = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_S") ?? "0";
var sq = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_SQ") ?? "verification";
var query = new Dictionary {
["method"] = "get_mails_by_alias",
["orderid"] = orderid,
["aliasid"] = aliasid,
["t"] = t,
["s"] = s,
["sq"] = sq
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
String aliasid = env("SMSPVA_EMAIL_ALIAS_ID", null);
String t = env("SMSPVA_EMAIL_T", "50");
String s = env("SMSPVA_EMAIL_S", "0");
String sq = env("SMSPVA_EMAIL_SQ", "verification");
Map query = new LinkedHashMap<>();
query.put("method", "get_mails_by_alias");
query.put("orderid", orderid);
query.put("aliasid", aliasid);
query.put("t", t);
query.put("s", s);
query.put("sq", sq);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": [
{
"id": 6,
"sender": "noreply@example.com",
"subject": "Verification code",
"preview": "Your code: 12345",
"addedAt": "2026-10-22T10:00:00.000Z"
}
]
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Empty result**
```json
{
"status": 1,
"data": []
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].id`** | integer | ID del mensaje; pásalo como **`emailid`** a get_mail_body. |
| **`data[].sender`** | string | Dirección del remitente. |
| **`data[].subject`** | string | Asunto del mensaje. |
| **`data[].preview`** | string | Vista previa del mensaje. |
| **`data[].addedAt`** | string | Fecha y hora del mensaje. (**`format: "date-time"`**) |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Pedidos archivados (/es/docs/email/archived)
GET{"https://smspva.com/api/rent_email.php?method=get_archived_orders"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "get_archived_orders" | Método que se va a ejecutar. |
## Cómo usar este método [#cómo-usar-este-método]
Consulta los alquileres archivados. Antes de restaurar uno, envía su **`id`** a [Coste de restauración](/es/docs/email/restoration-cost) para comprobar el precio actual; después usa [Restaurar alquiler](/es/docs/email/restore).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_archived_orders" \
--data-urlencode "apikey=$SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "get_archived_orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "get_archived_orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
query = {
"method": "get_archived_orders"
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_archived_orders'
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
query := url.Values{}
query.Set("method", "get_archived_orders")
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var query = new Dictionary {
["method"] = "get_archived_orders"
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
Map query = new LinkedHashMap<>();
query.put("method", "get_archived_orders");
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": [
{
"id": 123455,
"address": "archived@outlook.com",
"scode": "twitter",
"pcode": "outlookcom",
"expireDate": 1767225600,
"sname": "Twitter"
}
]
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].id`** | integer | ID del pedido archivado que quieres restaurar. |
| **`data[].address`** | string | Dirección de correo. |
| **`data[].scode`** | string | Código del servicio. |
| **`data[].pcode`** | string | Código del proveedor. |
| **`data[].expireDate`** | integer | Vencimiento del alquiler, como timestamp Unix en segundos. |
| **`data[].sname`** | string | Nombre visible del servicio. |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Comprar acceso a alias (/es/docs/email/buy-alias)
GET{"https://smspva.com/api/rent_email.php?method=buy_alias"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "buy_alias" | Método que se va a ejecutar. |
| **`orderid`** | query | integer | Sí | 123456 | ID de Create Order, Active Orders o Archived Orders, según el método que vayas a usar. |
| **`aliasid`** | query | integer | Sí | 88 | ID de un alias existente, tomado de aliases en Active Orders. **`orderid`** debe ser el ID del pedido padre. |
## Cómo usar este método [#cómo-usar-este-método]
Compra acceso a un alias de Gmail existente. Obtén **`aliasid`** de **`aliases`** en [Pedidos activos](/es/docs/email/orders) y envía el ID del pedido padre como **`orderid`**. Outlook no admite alias.
La solicitud compra acceso al alias que ya figura en el pedido; no crea uno nuevo. No hay un método público para generar alias. Después usa [Mensajes del alias](/es/docs/email/alias-messages).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
- **`SMSPVA_EMAIL_ALIAS_ID`**: **`aliasid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
: "${SMSPVA_EMAIL_ALIAS_ID:?Set SMSPVA_EMAIL_ALIAS_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=buy_alias" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID" \
--data-urlencode "aliasid=$SMSPVA_EMAIL_ALIAS_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const aliasid = required("SMSPVA_EMAIL_ALIAS_ID");
const query = new URLSearchParams({
"method": "buy_alias",
"orderid": orderid,
"aliasid": aliasid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const aliasid = required("SMSPVA_EMAIL_ALIAS_ID");
const query = new URLSearchParams({
"method": "buy_alias",
"orderid": orderid,
"aliasid": aliasid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
aliasid = os.environ["SMSPVA_EMAIL_ALIAS_ID"]
query = {
"method": "buy_alias",
"orderid": orderid,
"aliasid": aliasid
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'buy_alias',
'orderid' => $orderid,
'aliasid' => $aliasid
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
aliasid := env("SMSPVA_EMAIL_ALIAS_ID", "")
query := url.Values{}
query.Set("method", "buy_alias")
query.Set("orderid", orderid)
query.Set("aliasid", aliasid)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var aliasid = Required("SMSPVA_EMAIL_ALIAS_ID");
var query = new Dictionary {
["method"] = "buy_alias",
["orderid"] = orderid,
["aliasid"] = aliasid
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
String aliasid = env("SMSPVA_EMAIL_ALIAS_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "buy_alias");
query.put("orderid", orderid);
query.put("aliasid", aliasid);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": {
"alias": "sam.ple@gmail.com"
}
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | object | |
| **`data.alias`** | string | Dirección del alias. |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Cancelar alquiler (/es/docs/email/cancel)
GET{"https://smspva.com/api/rent_email.php?method=cancel_order"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "cancel_order" | Método que se va a ejecutar. |
| **`orderid`** | query | integer | Sí | 123456 | ID de Create Order, Active Orders o Archived Orders, según el método que vayas a usar. |
## Cómo usar este método [#cómo-usar-este-método]
Cancela un alquiler de la cuenta asociada a tu clave API. Usa el ID de [Pedidos activos](/es/docs/email/orders). La cancelación no garantiza un reembolso.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=cancel_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "cancel_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "cancel_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
query = {
"method": "cancel_order",
"orderid": orderid
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'cancel_order',
'orderid' => $orderid
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "cancel_order")
query.Set("orderid", orderid)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var query = new Dictionary {
["method"] = "cancel_order",
["orderid"] = orderid
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "cancel_order");
query.put("orderid", orderid);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": true
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | boolean | |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Disponibilidad de buzones (/es/docs/email/counts)
GET{"https://smspva.com/api/rent_email.php?method=get_count"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
## Autenticación [#autenticación]
Puedes llamar a este método sin clave API.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "get_count" | Método que se va a ejecutar. |
| **`pcode`** | query | string | No | "outlookcom" | Código de Get Providers. Para aceptar cualquier proveedor, omite este parámetro por completo; no envíes un valor vacío ni null. |
## Cómo usar este método [#cómo-usar-este-método]
Consulta los buzones disponibles por servicio. Envía **`pcode`** para un proveedor u omítelo para incluir todos los habilitados. Relaciona las entradas por **`scode`**: un servicio ausente tiene **cero** buzones; un array **`data`** vacío indica que no hay existencias.
Los recuentos pueden tener **15 segundos** de caché y no reservan buzones. Al cambiar de proveedor, sustituye los recuentos anteriores e ignora respuestas de selecciones previas. Usa el mismo proveedor al [crear el pedido](/es/docs/email/create).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
Define **`SMSPVA_EMAIL_PCODE`** con un proveedor actual; sin valor se omite **`pcode`** por completo. Usa los códigos de las listas dinámicas.
```bash
provider_args=()
if [ -n "${SMSPVA_EMAIL_PCODE:-}" ]; then provider_args=(--data-urlencode "pcode=$SMSPVA_EMAIL_PCODE"); fi
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_count" \
"${provider_args[@]}"
```
```js
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const query = new URLSearchParams({
"method": "get_count",
"pcode": pcode
});
if (!pcode) query.delete("pcode");
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const query = new URLSearchParams({
"method": "get_count",
"pcode": pcode
});
if (!pcode) query.delete("pcode");
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
pcode = os.environ.get("SMSPVA_EMAIL_PCODE", "")
query = {
"method": "get_count",
"pcode": pcode
}
if not pcode:
del query["pcode"]
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_count',
'pcode' => $pcode
];
if ($pcode === '') unset($query['pcode']);
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
pcode := os.Getenv("SMSPVA_EMAIL_PCODE")
query := url.Values{}
query.Set("method", "get_count")
query.Set("pcode", pcode)
if pcode == "" { query.Del("pcode") }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var pcode = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_PCODE") ?? "";
var query = new Dictionary {
["method"] = "get_count",
["pcode"] = pcode
};
if (string.IsNullOrEmpty(pcode)) query.Remove("pcode");
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String pcode = env("SMSPVA_EMAIL_PCODE", "");
Map query = new LinkedHashMap<>();
query.put("method", "get_count");
query.put("pcode", pcode);
if (pcode.isEmpty()) query.remove("pcode");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": [
{
"count": 40,
"scode": "twitter"
},
{
"count": 38,
"scode": "fb"
}
]
}
```
**Error**
```json
{
"status": 0,
"msg": "Provider not found"
}
```
**Empty result**
```json
{
"status": 1,
"data": []
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].count`** | integer | Cantidad de buzones disponibles. |
| **`data[].scode`** | string | Código del servicio. |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Crear alquiler (/es/docs/email/create)
GET{"https://smspva.com/api/rent_email.php?method=create_order"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "create_order" | Método que se va a ejecutar. |
| **`scode`** | query | string | Sí | "twitter" | Código obtenido de Services and Prices. |
| **`pcode`** | query | string | No | "outlookcom" | Código de Get Providers. Para aceptar cualquier proveedor, omite este parámetro por completo; no envíes un valor vacío ni null. |
| **`dtype`** | query | string | Sí | "week" | Unidad de alquiler: day = 1 día, week = 7 días, month = 30 días. |
| **`dcount`** | query | integer | Sí | 1 | Número positivo de unidades de alquiler. |
## Cómo usar este método [#cómo-usar-este-método]
Alquila un buzón para el servicio y la duración elegidos. Obtén **`scode`** y los precios en [Servicios](/es/docs/email/services), y **`pcode`** en [Proveedores](/es/docs/email/providers).
Para aceptar cualquier proveedor, omite **`pcode`** por completo. No envíes **`pcode=`**, una cadena vacía ni null. Si eliges un proveedor, la API usará solo ese, aunque se quede sin buzones.
La duración es **`dcount`** × **1**, **7** o **30** días para **`day`**, **`week`** o **`month`**. El coste se calcula con el precio diario; **`months_discount`** se aplica desde **30 días**. **`status=2`** indica que no había buzones: actualiza la [disponibilidad](/es/docs/email/counts) antes de repetir.
Guarda **`data.id`** como **`orderid`**, junto con la dirección, el proveedor real y el vencimiento. Usa ese ID para [leer mensajes](/es/docs/email/messages) y consultar [pedidos activos](/es/docs/email/orders).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
Define **`SMSPVA_EMAIL_PCODE`** con un proveedor actual; sin valor se omite **`pcode`** por completo. Usa los códigos de las listas dinámicas.
- **`SMSPVA_EMAIL_SCODE`**: **`scode`**.
```bash
provider_args=()
if [ -n "${SMSPVA_EMAIL_PCODE:-}" ]; then provider_args=(--data-urlencode "pcode=$SMSPVA_EMAIL_PCODE"); fi
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_SCODE:?Set SMSPVA_EMAIL_SCODE}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=create_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
"${provider_args[@]}" \
--data-urlencode "scode=$SMSPVA_EMAIL_SCODE" \
--data-urlencode "dtype=${SMSPVA_EMAIL_DTYPE:-week}" \
--data-urlencode "dcount=${SMSPVA_EMAIL_DCOUNT:-1}"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const scode = required("SMSPVA_EMAIL_SCODE");
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const dtype = process.env.SMSPVA_EMAIL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_EMAIL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "create_order",
"scode": scode,
"pcode": pcode,
"dtype": dtype,
"dcount": dcount
});
if (!pcode) query.delete("pcode");
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const scode = required("SMSPVA_EMAIL_SCODE");
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const dtype = process.env.SMSPVA_EMAIL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_EMAIL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "create_order",
"scode": scode,
"pcode": pcode,
"dtype": dtype,
"dcount": dcount
});
if (!pcode) query.delete("pcode");
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
scode = os.environ["SMSPVA_EMAIL_SCODE"]
pcode = os.environ.get("SMSPVA_EMAIL_PCODE", "")
dtype = os.environ.get("SMSPVA_EMAIL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_EMAIL_DCOUNT", "1")
query = {
"method": "create_order",
"scode": scode,
"pcode": pcode,
"dtype": dtype,
"dcount": dcount
}
if not pcode:
del query["pcode"]
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'create_order',
'scode' => $scode,
'pcode' => $pcode,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($pcode === '') unset($query['pcode']);
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
scode := env("SMSPVA_EMAIL_SCODE", "")
pcode := os.Getenv("SMSPVA_EMAIL_PCODE")
dtype := env("SMSPVA_EMAIL_DTYPE", "week")
dcount := env("SMSPVA_EMAIL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "create_order")
query.Set("scode", scode)
query.Set("pcode", pcode)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if pcode == "" { query.Del("pcode") }
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var scode = Required("SMSPVA_EMAIL_SCODE");
var pcode = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_PCODE") ?? "";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "create_order",
["scode"] = scode,
["pcode"] = pcode,
["dtype"] = dtype,
["dcount"] = dcount
};
if (string.IsNullOrEmpty(pcode)) query.Remove("pcode");
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String scode = env("SMSPVA_EMAIL_SCODE", null);
String pcode = env("SMSPVA_EMAIL_PCODE", "");
String dtype = env("SMSPVA_EMAIL_DTYPE", "week");
String dcount = env("SMSPVA_EMAIL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "create_order");
query.put("scode", scode);
query.put("pcode", pcode);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (pcode.isEmpty()) query.remove("pcode");
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Proveedor desconocido o desactivado**
```json
{
"status": 0,
"errorid": 9,
"errormsg": "Provider not found",
"msg": "Provider not found"
}
```
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": {
"id": 123456,
"email": "mailbox@outlook.com",
"scode": "twitter",
"pcode": "outlookcom",
"expireDate": 1855324800
}
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**No hay buzones disponibles**
```json
{
"status": 2
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | object | |
| **`data.id`** | integer | ID del pedido; úsalo como **`orderid`** en las siguientes solicitudes. |
| **`data.email`** | string | Dirección de correo asignada. |
| **`data.scode`** | string | Código del servicio. |
| **`data.pcode`** | string | Código del proveedor asignado. |
| **`data.expireDate`** | integer | Vencimiento del alquiler, como timestamp Unix en segundos. |
Obligatorios: **`status`**, **`data`**
**No hay buzones disponibles**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [2]`**) |
Obligatorios: **`status`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Errores y códigos (/es/docs/email/errors)
## Comprueba el resultado [#comprueba-el-resultado]
HTTP **200** no confirma por sí solo el éxito. Lee **`status`**: **1** indica éxito, **0** error y **2** que no había buzones al crear. Los ejemplos que analizan JSON comprueban HTTP y **`status`**; cURL muestra el JSON para que lo revises.
El motivo puede estar en **`msg`**, **`errormsg`** o **`errorid`**. Algunos errores solo incluyen **`msg`**: no necesitas un código numérico para reconocer un fallo con **`status=0`**.
## Códigos de error [#códigos-de-error]
| **`errorid`** | Significado |
| --- | --- |
| **2** | Servicio desconocido o no disponible |
| **7** | Parámetros no válidos |
| **9** | Proveedor desconocido o desactivado |
| **10** | Límite de pedidos activos alcanzado |
| **16** | Solicitudes de creación demasiado frecuentes |
Con **`errorid=9`**, actualiza [Proveedores](/es/docs/email/providers). Con **`status=2`** al crear, actualiza la [disponibilidad](/es/docs/email/counts).
## Mensajes que puedes recibir [#mensajes-que-puedes-recibir]
**`Incorrect apikey`** indica una clave ausente o mal formada; **`Unknown apikey`**, que no se encontró la cuenta. **`User is not owner of order`** requiere la clave del propietario. Los errores de saldo incluyen **`Balance is not enough`** y **`Balance is lower than zero`** (saldo no positivo).
Estos son otros mensajes posibles. Al informar de un problema, conserva el texto original, **`status`** y los demás campos de error.
- **`Order not found`**
- **`Aliases are only available for Gmail`**
- **`Incorrect service code`**
- **`Incorrect duration type`**
- **`Incorrect duration count`**
- **`Incorrect order id`**
- **`Incorrect email id`**
- **`Email service temporarily unavailable`**
- **`Incorrect method`**
# Ejemplos y entorno (/es/docs/email/examples)
Cada método incluye los mismos ocho lenguajes. Usa códigos actuales y tus propios IDs. Configura solo las variables del método elegido. Los comandos y dependencias técnicas se indican a continuación.
## Entorno [#entorno]
| Lenguaje | Entorno |
| --- | --- |
| cURL | Bash y cURL 7.76+; comprueba status en la respuesta JSON |
| JavaScript / TypeScript | Node.js 22+; TypeScript 5+ con tipos de Node |
| Python | Python 3.10+, biblioteca estándar |
| PHP | PHP 8.1+ y ext-curl |
| Go | Go 1.22+, biblioteca estándar |
| C# | .NET 8+, aplicación de consola |
| Java | Java 11+, Jackson Databind en el classpath |
Java usa Jackson para comprobar status en el JSON. Dependencia Maven ([Maven Central](https://central.sonatype.com/artifact/com.fasterxml.jackson.core/jackson-databind)):
```xml
com.fasterxml.jackson.core
jackson-databind
2.22.4
```
```bash
# Bash / macOS / Linux
export SMSPVA_API_KEY='YOUR_API_KEY'
export SMSPVA_EMAIL_SCODE='CODE_FROM_LIVE_SERVICES'
export SMSPVA_EMAIL_ORDER_ID='YOUR_EMAIL_ORDER_ID'
export SMSPVA_EMAIL_MESSAGE_ID='ID_FROM_GET_MAILS'
export SMSPVA_EMAIL_ALIAS_ID='ID_FROM_ORDER_ALIASES'
# Optional: set SMSPVA_EMAIL_PCODE from get_providers; unset means any provider.
unset SMSPVA_EMAIL_PCODE
```
```powershell
$env:SMSPVA_API_KEY = 'YOUR_API_KEY'
$env:SMSPVA_EMAIL_SCODE = 'CODE_FROM_LIVE_SERVICES'
$env:SMSPVA_EMAIL_ORDER_ID = 'YOUR_EMAIL_ORDER_ID'
$env:SMSPVA_EMAIL_MESSAGE_ID = 'ID_FROM_GET_MAILS'
$env:SMSPVA_EMAIL_ALIAS_ID = 'ID_FROM_ORDER_ALIASES'
Remove-Item Env:SMSPVA_EMAIL_PCODE -ErrorAction SilentlyContinue
```
| Variable | Parámetro |
| --- | --- |
| **`SMSPVA_EMAIL_DTYPE`** | **`dtype`**; valor predeterminado week |
| **`SMSPVA_EMAIL_DCOUNT`** | **`dcount`**; valor predeterminado 1 |
| **`SMSPVA_EMAIL_T`** | **`t`**, page size, default 50 |
| **`SMSPVA_EMAIL_S`** | **`s`**, offset, default 0 |
| **`SMSPVA_EMAIL_SQ`** | **`sq`**, search, example verification |
| **`SMSPVA_EMAIL_PCODE`** | **`pcode`**; se omite si no tiene valor |
Ejecuta los ejemplos cURL en Bash. Guarda Java como **`Example.java`**, Go como **`main.go`** y C# como **`Program.cs`** en un proyecto de consola .NET. Compila TypeScript antes de ejecutarlo. Los demás ejemplos leen directamente las variables de entorno.
Las solicitudes codifican los parámetros y usan un timeout de 30 segundos. Las claves viajan en la URL: ocúltalas en los registros públicos. Los métodos de listas públicas no envían la clave, aunque esté configurada.
Usa IDs de correo de tu propia cuenta. Los ejemplos no repiten automáticamente solicitudes de pago; comprueba el pedido si no sabes si la operación se completó.
# Private Email Rental API (/es/docs/email)
Endpoint: **https://smspva.com/api/rent_email.php**. Los 14 métodos usan **GET** y **method**. La clave del propietario se envía como **apikey en query**. Incluso con HTTP 200, comprueba **status**: **1** éxito, **0** error, **2** sin buzones al crear. Los detalles usan **msg**, **errormsg** y **errorid**.
## Datos de referencia [#datos-de-referencia]
| method | Descripción |
| --- | --- |
| **`get_providers`** | [Proveedores](/es/docs/email/providers) |
| **`get_data`** | [Servicios y precios](/es/docs/email/services) |
| **`get_count`** | [Disponibilidad de buzones](/es/docs/email/counts) |
## Buzones y mensajes [#buzones-y-mensajes]
| method | Descripción |
| --- | --- |
| **`create_order`** | [Crear alquiler](/es/docs/email/create) |
| **`get_orders`** | [Pedidos activos](/es/docs/email/orders) |
| **`get_mails`** | [Listar mensajes](/es/docs/email/messages) |
| **`get_mail_body`** | [Contenido del mensaje](/es/docs/email/message-body) |
## Gestionar alquileres y alias [#gestionar-alquileres-y-alias]
| method | Descripción |
| --- | --- |
| **`buy_alias`** | [Comprar acceso a alias](/es/docs/email/buy-alias) |
| **`get_mails_by_alias`** | [Mensajes del alias](/es/docs/email/alias-messages) |
| **`prolong_order`** | [Ampliar alquiler](/es/docs/email/prolong) |
| **`cancel_order`** | [Cancelar alquiler](/es/docs/email/cancel) |
## Archivo y restauración [#archivo-y-restauración]
| method | Descripción |
| --- | --- |
| **`get_archived_orders`** | [Pedidos archivados](/es/docs/email/archived) |
| **`calc_restore_order`** | [Coste de restauración](/es/docs/email/restoration-cost) |
| **`restore_order`** | [Restaurar alquiler](/es/docs/email/restore) |
# Contenido del mensaje (/es/docs/email/message-body)
GET{"https://smspva.com/api/rent_email.php?method=get_mail_body"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "get_mail_body" | Método que se va a ejecutar. |
| **`orderid`** | query | integer | Sí | 123456 | ID de Create Order, Active Orders o Archived Orders, según el método que vayas a usar. |
| **`emailid`** | query | integer | Sí | 6 | ID devuelto al consultar la lista de mensajes. |
## Cómo usar este método [#cómo-usar-este-método]
Lee el mensaje completo con el **`emailid`** de [Mensajes](/es/docs/email/messages) o [Mensajes del alias](/es/docs/email/alias-messages). Envía también el **`orderid`** del alquiler padre.
**`body`** puede contener HTML del remitente. Trátalo como contenido no fiable y sanéalo antes de mostrarlo en tu aplicación.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
- **`SMSPVA_EMAIL_MESSAGE_ID`**: **`emailid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
: "${SMSPVA_EMAIL_MESSAGE_ID:?Set SMSPVA_EMAIL_MESSAGE_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_mail_body" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID" \
--data-urlencode "emailid=$SMSPVA_EMAIL_MESSAGE_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const emailid = required("SMSPVA_EMAIL_MESSAGE_ID");
const query = new URLSearchParams({
"method": "get_mail_body",
"orderid": orderid,
"emailid": emailid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const emailid = required("SMSPVA_EMAIL_MESSAGE_ID");
const query = new URLSearchParams({
"method": "get_mail_body",
"orderid": orderid,
"emailid": emailid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
emailid = os.environ["SMSPVA_EMAIL_MESSAGE_ID"]
query = {
"method": "get_mail_body",
"orderid": orderid,
"emailid": emailid
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_mail_body',
'orderid' => $orderid,
'emailid' => $emailid
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
emailid := env("SMSPVA_EMAIL_MESSAGE_ID", "")
query := url.Values{}
query.Set("method", "get_mail_body")
query.Set("orderid", orderid)
query.Set("emailid", emailid)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var emailid = Required("SMSPVA_EMAIL_MESSAGE_ID");
var query = new Dictionary {
["method"] = "get_mail_body",
["orderid"] = orderid,
["emailid"] = emailid
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
String emailid = env("SMSPVA_EMAIL_MESSAGE_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "get_mail_body");
query.put("orderid", orderid);
query.put("emailid", emailid);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": {
"id": 6,
"sender": "noreply@example.com",
"subject": "Verification code",
"body": "Your code: 12345
",
"addedAt": "2026-10-22T10:00:00.000Z"
}
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | object | |
| **`data.id`** | integer | ID del mensaje. |
| **`data.sender`** | string | Dirección del remitente. |
| **`data.subject`** | string | Asunto del mensaje. |
| **`data.body`** | string | Contenido del mensaje; puede incluir HTML. Sanéalo antes de mostrarlo. |
| **`data.addedAt`** | string | Fecha y hora del mensaje. (**`format: "date-time"`**) |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Listar mensajes (/es/docs/email/messages)
GET{"https://smspva.com/api/rent_email.php?method=get_mails"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "get_mails" | Método que se va a ejecutar. |
| **`orderid`** | query | integer | Sí | 123456 | ID de Create Order, Active Orders o Archived Orders, según el método que vayas a usar. |
| **`t`** | query | integer | No | 50 | Número de resultados por página. |
| **`s`** | query | integer | No | 0 | Número de resultados que se omiten al paginar. |
| **`sq`** | query | string | No | "verification" | Texto de búsqueda. Codifícalo para enviarlo en la URL. |
## Cómo usar este método [#cómo-usar-este-método]
Consulta las vistas previas de los mensajes de un alquiler tuyo. Obtén **`orderid`** en [Pedidos activos](/es/docs/email/orders). Usa **`t`** como tamaño de página, **`s`** como desplazamiento y codifica en URL el filtro opcional **`sq`**.
Para leer el mensaje completo, envía su **`id`** como **`emailid`** a [Contenido del mensaje](/es/docs/email/message-body). Un array **`data`** vacío significa que la consulta funcionó, pero no encontró mensajes.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_mails" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID" \
--data-urlencode "t=${SMSPVA_EMAIL_T:-50}" \
--data-urlencode "s=${SMSPVA_EMAIL_S:-0}" \
--data-urlencode "sq=${SMSPVA_EMAIL_SQ:-verification}"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const t = process.env.SMSPVA_EMAIL_T ?? "50";
const s = process.env.SMSPVA_EMAIL_S ?? "0";
const sq = process.env.SMSPVA_EMAIL_SQ ?? "verification";
const query = new URLSearchParams({
"method": "get_mails",
"orderid": orderid,
"t": t,
"s": s,
"sq": sq
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const t = process.env.SMSPVA_EMAIL_T ?? "50";
const s = process.env.SMSPVA_EMAIL_S ?? "0";
const sq = process.env.SMSPVA_EMAIL_SQ ?? "verification";
const query = new URLSearchParams({
"method": "get_mails",
"orderid": orderid,
"t": t,
"s": s,
"sq": sq
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
t = os.environ.get("SMSPVA_EMAIL_T", "50")
s = os.environ.get("SMSPVA_EMAIL_S", "0")
sq = os.environ.get("SMSPVA_EMAIL_SQ", "verification")
query = {
"method": "get_mails",
"orderid": orderid,
"t": t,
"s": s,
"sq": sq
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_mails',
'orderid' => $orderid,
't' => $t,
's' => $s,
'sq' => $sq
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
t := env("SMSPVA_EMAIL_T", "50")
s := env("SMSPVA_EMAIL_S", "0")
sq := env("SMSPVA_EMAIL_SQ", "verification")
query := url.Values{}
query.Set("method", "get_mails")
query.Set("orderid", orderid)
query.Set("t", t)
query.Set("s", s)
query.Set("sq", sq)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var t = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_T") ?? "50";
var s = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_S") ?? "0";
var sq = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_SQ") ?? "verification";
var query = new Dictionary {
["method"] = "get_mails",
["orderid"] = orderid,
["t"] = t,
["s"] = s,
["sq"] = sq
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
String t = env("SMSPVA_EMAIL_T", "50");
String s = env("SMSPVA_EMAIL_S", "0");
String sq = env("SMSPVA_EMAIL_SQ", "verification");
Map query = new LinkedHashMap<>();
query.put("method", "get_mails");
query.put("orderid", orderid);
query.put("t", t);
query.put("s", s);
query.put("sq", sq);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": [
{
"id": 6,
"sender": "noreply@example.com",
"subject": "Verification code",
"preview": "Your code: 12345",
"addedAt": "2026-10-22T10:00:00.000Z"
}
]
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Empty result**
```json
{
"status": 1,
"data": []
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].id`** | integer | ID del mensaje; pásalo como **`emailid`** a get_mail_body. |
| **`data[].sender`** | string | Dirección del remitente. |
| **`data[].subject`** | string | Asunto del mensaje. |
| **`data[].preview`** | string | Vista previa del mensaje. |
| **`data[].addedAt`** | string | Fecha y hora del mensaje. (**`format: "date-time"`**) |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Pedidos activos (/es/docs/email/orders)
GET{"https://smspva.com/api/rent_email.php?method=get_orders"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "get_orders" | Método que se va a ejecutar. |
## Cómo usar este método [#cómo-usar-este-método]
Consulta los alquileres activos, sus mensajes y los alias disponibles. Aquí la dirección se llama **`address`**; en [Crear alquiler](/es/docs/email/create) se llama **`email`**.
Usa el ID para [leer mensajes](/es/docs/email/messages) o [ampliar el alquiler](/es/docs/email/prolong). Los pedidos de Gmail pueden incluir **`aliases[].id`** para [comprar acceso](/es/docs/email/buy-alias); Outlook no admite alias. Los alquileres terminados están en [Pedidos archivados](/es/docs/email/archived).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_orders" \
--data-urlencode "apikey=$SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "get_orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "get_orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
query = {
"method": "get_orders"
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_orders'
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
query := url.Values{}
query.Set("method", "get_orders")
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var query = new Dictionary {
["method"] = "get_orders"
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
Map query = new LinkedHashMap<>();
query.put("method", "get_orders");
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": [
{
"id": 123456,
"address": "mailbox@outlook.com",
"scode": "twitter",
"pcode": "outlookcom",
"expireDate": 1855324800,
"mesCount": 1,
"aliases": [],
"sname": "Twitter"
},
{
"id": 123457,
"address": "sample@gmail.com",
"scode": "twitter",
"pcode": "gmailcom",
"expireDate": 1855324800,
"mesCount": 0,
"aliases": [
{
"id": 88,
"address": "sam.ple@gmail.com",
"mesCount": 1,
"isPaid": false
}
],
"sname": "Twitter"
}
]
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].id`** | integer | ID del pedido. |
| **`data[].address`** | string | Dirección de correo. En create_order este campo se llama email. |
| **`data[].scode`** | string | Código del servicio. |
| **`data[].pcode`** | string | Código del proveedor. |
| **`data[].expireDate`** | integer | Vencimiento del alquiler, como timestamp Unix en segundos. |
| **`data[].mesCount`** | integer | Cantidad de mensajes. |
| **`data[].aliases`** | array<object> | |
| **`data[].aliases[].id`** | integer | ID del alias existente; úsalo como **`aliasid`**. |
| **`data[].aliases[].address`** | string | Dirección de correo del alias. |
| **`data[].aliases[].mesCount`** | integer | Cantidad de mensajes del alias. |
| **`data[].aliases[].isPaid`** | boolean | Indica si ya se ha pagado el acceso al alias. |
| **`data[].sname`** | string | Nombre visible del servicio. |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Ampliar alquiler (/es/docs/email/prolong)
GET{"https://smspva.com/api/rent_email.php?method=prolong_order"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "prolong_order" | Método que se va a ejecutar. |
| **`orderid`** | query | integer | Sí | 123456 | ID de Create Order, Active Orders o Archived Orders, según el método que vayas a usar. |
| **`dtype`** | query | string | Sí | "week" | Unidad de alquiler: day = 1 día, week = 7 días, month = 30 días. |
| **`dcount`** | query | integer | Sí | 1 | Número positivo de unidades de alquiler. |
## Cómo usar este método [#cómo-usar-este-método]
Amplía un alquiler con el ID de [Pedidos activos](/es/docs/email/orders). El coste se descuenta del saldo. **`dcount`** debe ser positivo; **`day`**, **`week`** y **`month`** equivalen a **1**, **7** y **30** días por unidad.
Si está configurado, el descuento del servicio se aplica a ampliaciones de al menos **30 días**. Actualiza los pedidos activos después para obtener el nuevo vencimiento: esta respuesta no lo incluye.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=prolong_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID" \
--data-urlencode "dtype=${SMSPVA_EMAIL_DTYPE:-week}" \
--data-urlencode "dcount=${SMSPVA_EMAIL_DCOUNT:-1}"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const dtype = process.env.SMSPVA_EMAIL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_EMAIL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "prolong_order",
"orderid": orderid,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const dtype = process.env.SMSPVA_EMAIL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_EMAIL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "prolong_order",
"orderid": orderid,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
dtype = os.environ.get("SMSPVA_EMAIL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_EMAIL_DCOUNT", "1")
query = {
"method": "prolong_order",
"orderid": orderid,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'prolong_order',
'orderid' => $orderid,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
dtype := env("SMSPVA_EMAIL_DTYPE", "week")
dcount := env("SMSPVA_EMAIL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "prolong_order")
query.Set("orderid", orderid)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "prolong_order",
["orderid"] = orderid,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
String dtype = env("SMSPVA_EMAIL_DTYPE", "week");
String dcount = env("SMSPVA_EMAIL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "prolong_order");
query.put("orderid", orderid);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": {
"id": 123456,
"email": "mailbox@outlook.com",
"service": "Twitter"
}
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | object | |
| **`data.id`** | integer | ID del pedido. |
| **`data.email`** | string | Dirección de correo. |
| **`data.service`** | string | Nombre visible del servicio, distinto de su código. |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Proveedores (/es/docs/email/providers)
GET{"https://smspva.com/api/rent_email.php?method=get_providers"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
## Autenticación [#autenticación]
Puedes llamar a este método sin clave API.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "get_providers" | Método que se va a ejecutar. |
## Cómo usar este método [#cómo-usar-este-método]
Consulta los proveedores de correo habilitados y usa sus valores **`pcode`** para crear el selector. Actualiza esta lista en lugar de mantener códigos fijos. Un proveedor habilitado puede no tener buzones para un servicio concreto.
Usa el mismo **`pcode`** en [servicios y precios](/es/docs/email/services), [disponibilidad](/es/docs/email/counts) y [crear un pedido](/es/docs/email/create).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_providers"
```
```js
const query = new URLSearchParams({
"method": "get_providers"
});
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
const query = new URLSearchParams({
"method": "get_providers"
});
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
query = {
"method": "get_providers"
}
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_providers'
];
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
query := url.Values{}
query.Set("method", "get_providers")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var query = new Dictionary {
["method"] = "get_providers"
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
Map query = new LinkedHashMap<>();
query.put("method", "get_providers");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": [
{
"id": 2,
"pcode": "gmailcom",
"name": "Gmail"
},
{
"id": 6,
"pcode": "outlookcom",
"name": "Microsoft Outlook"
}
]
}
```
**Error**
```json
{
"status": 0,
"msg": "Provider not found"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].id`** | integer | ID del proveedor. |
| **`data[].pcode`** | string | Código del proveedor para filtrar y crear pedidos. |
| **`data[].name`** | string | Nombre que se muestra. |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Proveedores y servicios (/es/docs/email/reference-data)
Elige un proveedor para ver sus servicios, precios diarios y buzones disponibles. **Todos los proveedores** suma los habilitados y omite **`pcode`** de la solicitud. Los precios son USD por día; solo Gmail permite acceso a alias.
Las listas se actualizan al abrir o volver a la página, cambiar de proveedor y cada **minuto** mientras esté visible. Los recuentos pueden tener **15 segundos** de caché. Si un servicio no aparece en la respuesta de cantidades, tiene cero buzones. Consultar disponibilidad no reserva un buzón.
# Coste de restauración (/es/docs/email/restoration-cost)
GET{"https://smspva.com/api/rent_email.php?method=calc_restore_order"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "calc_restore_order" | Método que se va a ejecutar. |
| **`orderid`** | query | integer | Sí | 123456 | ID de Create Order, Active Orders o Archived Orders, según el método que vayas a usar. |
## Cómo usar este método [#cómo-usar-este-método]
Consulta el coste actual de restaurar un pedido de [Pedidos archivados](/es/docs/email/archived). **`data`** es un valor numérico en USD.
Esta consulta no restaura el alquiler ni cobra. Como el precio puede cambiar, hazla justo antes de [Restaurar alquiler](/es/docs/email/restore).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=calc_restore_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "calc_restore_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "calc_restore_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
query = {
"method": "calc_restore_order",
"orderid": orderid
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'calc_restore_order',
'orderid' => $orderid
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "calc_restore_order")
query.Set("orderid", orderid)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var query = new Dictionary {
["method"] = "calc_restore_order",
["orderid"] = orderid
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "calc_restore_order");
query.put("orderid", orderid);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": 0.7
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | number | Coste actual de restauración en USD. |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Restaurar alquiler (/es/docs/email/restore)
GET{"https://smspva.com/api/rent_email.php?method=restore_order"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Clave API de la cuenta. Para leer mensajes o gestionar un alquiler, usa la clave de su propietario. |
| **`method`** | query | string | Sí | "restore_order" | Método que se va a ejecutar. |
| **`orderid`** | query | integer | Sí | 123456 | ID de Create Order, Active Orders o Archived Orders, según el método que vayas a usar. |
## Cómo usar este método [#cómo-usar-este-método]
Restaura un alquiler archivado. Obtén el ID en [Pedidos archivados](/es/docs/email/archived) y consulta antes el [coste](/es/docs/email/restoration-cost); esta solicitud lo descuenta del saldo.
No se puede elegir una duración personalizada de restauración. Al terminar, actualiza [Pedidos activos](/es/docs/email/orders) para ver los datos del alquiler.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=restore_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
query = {
"method": "restore_order",
"orderid": orderid
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'restore_order',
'orderid' => $orderid
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "restore_order")
query.Set("orderid", orderid)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var query = new Dictionary {
["method"] = "restore_order",
["orderid"] = orderid
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "restore_order");
query.put("orderid", orderid);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": {
"id": 123455,
"email": "archived@outlook.com",
"service": "Twitter"
}
}
```
**Error**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | object | |
| **`data.id`** | integer | ID del pedido. |
| **`data.email`** | string | Dirección de correo. |
| **`data.service`** | string | Nombre visible del servicio, distinto de su código. |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Servicios y precios (/es/docs/email/services)
GET{"https://smspva.com/api/rent_email.php?method=get_data"}
Envía una solicitud **GET** y comprueba **`status`** incluso con HTTP **200**: **1** indica éxito, **0** fallo y **2** que no había buzones al crear el alquiler. Consulta los detalles en **`msg`**, **`errormsg`** y **`errorid`**.
## Autenticación [#autenticación]
Puedes llamar a este método sin clave API.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "get_data" | Método que se va a ejecutar. |
| **`pcode`** | query | string | No | "outlookcom" | Código de Get Providers. Para aceptar cualquier proveedor, omite este parámetro por completo; no envíes un valor vacío ni null. |
## Cómo usar este método [#cómo-usar-este-método]
Consulta servicios, precios diarios y cantidades de buzones. Envía un **`pcode`** de [Proveedores](/es/docs/email/providers) para filtrar o no lo incluyas para sumar los proveedores habilitados. Usa **`scode`** al [crear el alquiler](/es/docs/email/create).
Los precios están en USD. **`months_discount`** se aplica a períodos de al menos **30 días**. Solo Gmail permite alias. Actualiza la [disponibilidad](/es/docs/email/counts) al cambiar de proveedor.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/email/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
Define **`SMSPVA_EMAIL_PCODE`** con un proveedor actual; sin valor se omite **`pcode`** por completo. Usa los códigos de las listas dinámicas.
```bash
provider_args=()
if [ -n "${SMSPVA_EMAIL_PCODE:-}" ]; then provider_args=(--data-urlencode "pcode=$SMSPVA_EMAIL_PCODE"); fi
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_data" \
"${provider_args[@]}"
```
```js
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const query = new URLSearchParams({
"method": "get_data",
"pcode": pcode
});
if (!pcode) query.delete("pcode");
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const query = new URLSearchParams({
"method": "get_data",
"pcode": pcode
});
if (!pcode) query.delete("pcode");
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
pcode = os.environ.get("SMSPVA_EMAIL_PCODE", "")
query = {
"method": "get_data",
"pcode": pcode
}
if not pcode:
del query["pcode"]
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_data',
'pcode' => $pcode
];
if ($pcode === '') unset($query['pcode']);
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
pcode := os.Getenv("SMSPVA_EMAIL_PCODE")
query := url.Values{}
query.Set("method", "get_data")
query.Set("pcode", pcode)
if pcode == "" { query.Del("pcode") }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var pcode = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_PCODE") ?? "";
var query = new Dictionary {
["method"] = "get_data",
["pcode"] = pcode
};
if (string.IsNullOrEmpty(pcode)) query.Remove("pcode");
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String pcode = env("SMSPVA_EMAIL_PCODE", "");
Map query = new LinkedHashMap<>();
query.put("method", "get_data");
query.put("pcode", pcode);
if (pcode.isEmpty()) query.remove("pcode");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Comprueba status aunque HTTP sea 200. Los valores de los ejemplos son orientativos.
**application/json**
**Ejemplo de respuesta correcta**
```json
{
"status": 1,
"data": [
{
"count": 40,
"scode": "twitter",
"sname": "Twitter",
"price": 0.1,
"alias_price": 0.25,
"icon": "/templates/SMSv1EN/images/ico/twitter.png",
"months_discount": 20
}
]
}
```
**Error**
```json
{
"status": 0,
"msg": "Provider not found"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].count`** | integer | Cantidad de buzones disponibles. |
| **`data[].scode`** | string | Código del servicio para crear el pedido. |
| **`data[].sname`** | string | Nombre visible del servicio. |
| **`data[].price`** | number | Precio diario del alquiler en USD. |
| **`data[].alias_price`** | number | Precio del acceso al alias. Solo Gmail admite alias. |
| **`data[].icon`** | string | Ruta del icono del servicio. |
| **`data[].months_discount`** | integer | Porcentaje de descuento para alquileres de al menos 30 días. |
Obligatorios: **`status`**, **`data`**
**Error**
Algunos errores incluyen errorid y errormsg; otros solo msg. Comprueba todos los campos presentes.
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | Código numérico de error, si se incluye. |
| **`errormsg`** | string | Descripción del error, si se incluye. |
| **`msg`** | string | Mensaje de error. |
## Guías relacionadas [#guías-relacionadas]
- [Private Email Rental API](/es/docs/email)
- [Proveedores y servicios](/es/docs/email/reference-data)
- [Flujo de alquiler de email](/es/docs/email/workflow)
- [Errores](/es/docs/email/errors)
- [Esquema OpenAPI](/openapi/email.json)
# Flujo de alquiler de email (/es/docs/email/workflow)
## 1. Elige proveedor y servicio [#1-elige-proveedor-y-servicio]
Consulta [proveedores](/es/docs/email/providers), [servicios y precios](/es/docs/email/services) y [disponibilidad](/es/docs/email/counts). Usa el mismo **`pcode`**; omítelo completamente para cualquier proveedor, sin vacío ni null. La disponibilidad puede tener 15 segundos de caché y no reserva buzones.
## 2. Crea el alquiler [#2-crea-el-alquiler]
[Crea el alquiler](/es/docs/email/create) con **`scode`**, **`dtype`** y **`dcount`**. day/week/month equivalen a 1/7/30 días por unidad. **`months_discount`** aplica desde 30 días. Un proveedor elegido no tiene fallback. **`status=2`** significa sin existencias.
## 3. Guarda los datos del pedido [#3-guarda-los-datos-del-pedido]
Guarda **`data.id`**, email, **`pcode`** y **`expireDate`**. [Pedidos activos](/es/docs/email/orders) usa address en lugar de email; **`expireDate`** es Unix en segundos.
## 4. Lee los mensajes [#4-lee-los-mensajes]
[Lista mensajes](/es/docs/email/messages) con **`orderid`** y paginación t/s; sq requiere codificación URL. data=[] es éxito sin resultados. Usa el id del mensaje como **`emailid`** y su **`orderid`** padre para [leer el contenido](/es/docs/email/message-body). Sanea el HTML antes de mostrarlo.
## 5. Usa un alias de Gmail [#5-usa-un-alias-de-gmail]
Los alias son exclusivos de Gmail. Usa un aliases[].id existente de pedidos activos para [comprar acceso](/es/docs/email/buy-alias); no hay método documentado para generar alias. [Mensajes de alias](/es/docs/email/alias-messages) también requiere **`orderid`** del padre.
## 6. Amplía o cancela [#6-amplía-o-cancela]
[Amplía](/es/docs/email/prolong) y actualiza pedidos para ver la caducidad. [Cancelar](/es/docs/email/cancel) no garantiza reembolso.
## 7. Restaura un alquiler archivado [#7-restaura-un-alquiler-archivado]
Desde [archivo](/es/docs/email/archived), consulta el [coste actual](/es/docs/email/restoration-cost) antes de [restaurar](/es/docs/email/restore). Consultar no cobra; restaurar sí. No se admite duración personalizada. Actualiza pedidos activos.
No repitas automáticamente operaciones pagadas tras un timeout: comprueba primero el estado.
# Errores y límites (/es/docs/errors)
La tabla de cada método es la referencia. Un estado HTTP puede tener distintos significados según el método; no sustituyas los códigos de esta API por interpretaciones HTTP convencionales. Conserva **`statusCode`**, **`error.type`** y **`error.description`**.
## La espera no es un fallo final [#la-espera-no-es-un-fallo-final]
Receive SMS devuelve **202 / SMS_NOT_YET_RECEIVED** con el objeto error de forma intencionada. Trátalo antes de los errores generales y repite la consulta dentro del plazo del pedido.
## Límites y fallos de conexión [#límites-y-fallos-de-conexión]
Respeta los errores de límite documentados por método, como ACCESS_LIMITED. Consulta los límites y errores del método que estés usando. Un timeout o respuesta no JSON no equivale a un error API confirmado. Los ejemplos no reintentan automáticamente. Revisa los pedidos antes de repetir una solicitud de número incierta.
## Índice de respuestas [#índice-de-respuestas]
Un guion indica que la fuente no incluye un ejemplo estructurado del tipo de error. Se conservan las diferencias entre métodos.
| HTTP | **`error.type`** | Descripción | Métodos |
| --- | --- | --- | --- |
| 400 | APIKEY_NOT_SET | Falta la cabecera **`apikey`**, está vacía o su longitud no es válida. | [Consultar saldo](/es/docs/api/balance), [Información de usuario](/es/docs/api/userinfo) |
| 400 | APIKEY_NOT_SET | No se ha recibido la clave API. | [Operadores](/es/docs/api/operators), [Tasas de conversión](/es/docs/api/conversions), [Precios por país y operador](/es/docs/api/country-operator-prices) |
| 400 | APIKEY_NOT_SET | Falta la cabecera **`apikey`**, está vacía o tiene menos de 30 caracteres. | [Configuración de mensajes](/es/docs/api/country-service-settings) |
| 401 | USER_NOT_FOUND | No se encontró una cuenta para esa clave API. | [Configuración de mensajes](/es/docs/api/country-service-settings) |
| 402 | RATELIMIT_EXCEED | Se ha superado el límite de solicitudes. Esta API devuelve HTTP 402 para este error. | [Configuración de mensajes](/es/docs/api/country-service-settings) |
| 403 | USER_BANNED | La cuenta está bloqueada. | [Configuración de mensajes](/es/docs/api/country-service-settings) |
| 500 | SERVER_ERROR | Error interno. Si los detalles están habilitados, la descripción puede incluir la excepción. | [Configuración de mensajes](/es/docs/api/country-service-settings) |
| 402 | RATELIMIT_EXCEED | Se ha superado el límite de solicitudes. | [Disponibilidad de todos los números](/es/docs/api/countnumbers) |
| 405 | INVALID_PARAMS | country o service no es válido. | [Precio del servicio](/es/docs/api/service-price) |
| 405 | INVALID_PARAMS | Parámetros no válidos | [Precios del servicio por país](/es/docs/api/service-prices), [Obtener número](/es/docs/api/get-number), [Obtener número por operador](/es/docs/api/get-number-by-operator), [Recibir SMS](/es/docs/api/receive-sms), [Borrar SMS](/es/docs/api/clear-sms), [Detener SMS](/es/docs/api/stop-sms), [Cancelar pedido](/es/docs/api/cancel-order) |
| 407 | LOW_BALANCE | El saldo no alcanza para recibir SMS del país y servicio elegidos. | [Obtener número](/es/docs/api/get-number) |
| 411 | ACCESS_LIMITED | Acceso limitado por karma bajo o exceso de solicitudes. | [Obtener número](/es/docs/api/get-number), [Recibir SMS](/es/docs/api/receive-sms), [Detener SMS](/es/docs/api/stop-sms), [Cancelar pedido](/es/docs/api/cancel-order), [Bloquear número](/es/docs/api/block-number) |
| 500 | NUMBER_FETCH_FAIL | No se pudo obtener el número. | [Obtener número](/es/docs/api/get-number) |
| 501 | PRICE_FETCH_FAIL | No se encontró el número. | [Obtener número](/es/docs/api/get-number) |
| 502 | NUMBER_NOT_FOUND | No se encontró el número. | [Obtener número](/es/docs/api/get-number) |
| 503 | SERVER_BUSY | El servidor está sobrecargado. Inténtalo más tarde. | [Obtener número](/es/docs/api/get-number) |
| 407 | — | El saldo no alcanza para recibir SMS del país y servicio elegidos. | [Obtener número por operador](/es/docs/api/get-number-by-operator) |
| 411 | — | Acceso limitado por karma bajo o exceso de solicitudes. | [Obtener número por operador](/es/docs/api/get-number-by-operator) |
| 500 | — | No se pudo obtener el número. | [Obtener número por operador](/es/docs/api/get-number-by-operator) |
| 501 | — | No se encontró el número. | [Obtener número por operador](/es/docs/api/get-number-by-operator) |
| 502 | — | No se encontró el número. | [Obtener número por operador](/es/docs/api/get-number-by-operator), [Estado del número](/es/docs/api/number-status) |
| 503 | — | El servidor está sobrecargado. Inténtalo más tarde. | [Obtener número por operador](/es/docs/api/get-number-by-operator) |
| 406 | INVALID_ORDER_FORMAT | El ID del pedido no es válido o no se encontró. | [Recibir SMS](/es/docs/api/receive-sms) |
| 407 | LOW_BALANCE | Se ha recibido el SMS, pero el saldo no alcanza para pagarlo. | [Recibir SMS](/es/docs/api/receive-sms) |
| 410 | ORDER_CLOSED | El pedido está cerrado y ya no está disponible. | [Recibir SMS](/es/docs/api/receive-sms) |
| 500 | SMS_FETCH_FAIL | No se pudo obtener el SMS. | [Recibir SMS](/es/docs/api/receive-sms) |
| 501 | SERVER_FAIL | El servidor no pudo procesar la solicitud. | [Recibir SMS](/es/docs/api/receive-sms), [Pedidos actuales](/es/docs/api/orders), [Borrar SMS](/es/docs/api/clear-sms), [Detener SMS](/es/docs/api/stop-sms), [Bloquear número](/es/docs/api/block-number) |
| 503 | SERVER_BUSY | El servidor está sobrecargado. Inténtalo más tarde. | [Recibir SMS](/es/docs/api/receive-sms), [Pedidos actuales](/es/docs/api/orders), [Detener SMS](/es/docs/api/stop-sms), [Cancelar pedido](/es/docs/api/cancel-order), [Bloquear número](/es/docs/api/block-number) |
| 405 | INVALID_NUMBER_FORMAT | Formato de número no válido | [Estado del número](/es/docs/api/number-status) |
| 406 | ORDER_NOT_FOUND | El ID del pedido no es válido o no se encontró. | [Estado del número](/es/docs/api/number-status), [Detener SMS](/es/docs/api/stop-sms), [Cancelar pedido](/es/docs/api/cancel-order), [Bloquear número](/es/docs/api/block-number) |
| 500 | SERVER_ERROR | Error interno. La descripción puede incluir información de diagnóstico. | [Estado del número](/es/docs/api/number-status) |
| 501 | — | El servidor no pudo procesar la solicitud. | [Estado del número](/es/docs/api/number-status) |
| 503 | — | El servidor está sobrecargado. Inténtalo más tarde. | [Estado del número](/es/docs/api/number-status) |
| 504 | — | **`av2.resp.504.desc`**: la fuente no incluye una descripción desarrollada para esta respuesta. | [Estado del número](/es/docs/api/number-status) |
| 404 | NO_SMS_TO_CLEAN | No se ha recibido un SMS, o hay uno pendiente de pago. | [Borrar SMS](/es/docs/api/clear-sms) |
| 406 | ORDER_NOT_FOUND | No se encontró el pedido. | [Borrar SMS](/es/docs/api/clear-sms) |
| 503 | SERVER_BUSY | No se ha recibido un SMS, o hay uno pendiente de pago. | [Borrar SMS](/es/docs/api/clear-sms) |
| 501 | SERVER_BUSY | El servidor no pudo procesar la solicitud. | [Cancelar pedido](/es/docs/api/cancel-order) |
| 405 | INVALID_PARAMS | Formato de número no válido | [Bloquear número](/es/docs/api/block-number) |
# Ejemplos de código (/es/docs/examples)
Cada [método de Activation V2](/es/docs/api) incluye **cURL, JavaScript, TypeScript, Python, PHP, Go, C# y Java**. Son solicitudes HTTP directas con el método documentado y la cabecera **`apikey`**; no requieren un SDK de SMSPVA.
## Requisitos [#requisitos]
| Ejemplo | Entorno | Ejecución |
| --- | --- | --- |
| cURL | cURL 7.76+; shell POSIX en macOS, Linux o WSL | Pegar en el shell |
| JavaScript | Node.js 22.16+ | node Example.mjs |
| TypeScript | Proyecto Node.js ESM con tipos Node | Example.mts; compilar con NodeNext/ES2022 o usar tu ejecutor TS |
| Python | Python 3.10+, biblioteca estándar | python Example.py |
| PHP | PHP 8.1+ con ext-curl | php Example.php |
| Go | Go 1.20+, biblioteca estándar | go run Example.go |
| C# | Proyecto de consola .NET 8+ | Guardar en Program.cs; dotnet run |
| Java | JDK 11+, biblioteca estándar | java Example.java |
Java muestra el JSON sin analizar: usa la biblioteca JSON de tu aplicación para leer los campos. Los otros ejemplos analizan JSON. JavaScript y TypeScript se ejecutan en el servidor, no en el navegador.
## Variables de entorno [#variables-de-entorno]
```text
# macOS / Linux / WSL
export SMSPVA_API_KEY="YOUR_API_KEY"
```
```text
# PowerShell
$env:SMSPVA_API_KEY = "YOUR_API_KEY"
$env:SMSPVA_ORDER_ID = "123456" # Sustituir por tu pedido real
```
Los métodos de pedido requieren **SMSPVA_ORDER_ID**. Number status requiere **SMSPVA_NUMBER**, sin prefijo telefónico del país. País, servicio y operador usan valores ilustrativos del contrato; puedes cambiar el código o definir **SMSPVA_COUNTRY**, **SMSPVA_SERVICE**, **SMSPVA_OPERATOR**. En cURL, edita directamente los códigos literales.
Consulta los [códigos](/es/docs/reference-data) y [operadores](/es/docs/api/operators). Los ejemplos que admiten voice usan **voice=0**; para caller-ID usa 1 y para voz 2, según los [permisos](/es/docs/message-types).
Receive SMS admite además **partnerkey**, cabecera opcional de contabilidad de referidos. Se utiliza al recibir correctamente un SMS.
## Respuestas [#respuestas]
Tiempo de espera de cliente: 30 segundos. No hay reintentos automáticos. HTTP 202 / SMS_NOT_YET_RECEIVED se trata antes de los errores generales. cURL imprime el cuerpo; Java conserva el JSON para analizarlo en tu aplicación.
Consulta el [polling](/es/docs/activation-workflow). Tras una compra con resultado incierto, revisa los pedidos antes de repetirla.
# Bienvenido a SMSPVA (/es/docs)
## Tu primera integración [#tu-primera-integración]
Empieza con **Activation V2**. Consulta el saldo, interpreta la respuesta y continúa con los flujos de pedidos.
Configura tu clave API y envía tu primera solicitud.
Los 20 métodos con ejemplos en ocho lenguajes.
Los 22 métodos de alquiler, listas actualizadas y flujo completo.
14 métodos y ejemplos en ocho lenguajes
Elige un SDK para Python, JS/TS, PHP, Go, C# o Java.
Conecta el servidor MCP local y usa sus 56 herramientas API.
## Elige la API adecuada [#elige-la-api-adecuada]
| Familia | Uso | Documentación |
| --- | --- | --- |
| Activation V2 | Activación telefónica | [Referencia completa: 20 métodos](/es/docs/api) |
| Alquiler de números | Alquiler de mayor duración | [Referencia completa: 22 métodos](/es/docs/rental) |
| Alquiler de correo privado | Buzones y mensajes entrantes | [Referencia actual](/es/docs/email) |
La autenticación y los formatos de respuesta varían entre familias. Usa el servidor y el formato de credenciales de la API seleccionada.
## Qué encontrarás aquí [#qué-encontrarás-aquí]
La documentación cubre Activation V2, el alquiler de números y el alquiler de correo privado, con listas actualizadas y ejemplos en ocho lenguajes. Empieza por el flujo de la API que necesites y abre después cada método para consultar sus parámetros y respuestas. Hay SDKs alfa publicados para [Python en PyPI](https://pypi.org/project/smspva-sdk/), [JavaScript/TypeScript en npm](https://www.npmjs.com/package/smspva-sdk), [PHP en Packagist](https://packagist.org/packages/smspva/sdk), [Go en pkg.go.dev](https://pkg.go.dev/github.com/SMSPVA/smspva-go), [C#/.NET en NuGet](https://www.nuget.org/packages/Smspva.Sdk/0.1.0-alpha.1) y [Java en Maven Central](https://central.sonatype.com/artifact/com.smspva/smspva-sdk/0.1.0-alpha.1). Ambos servidores MCP siguen como versiones alfa locales.
# MCP y herramientas de IA (/es/docs/mcp)
## Conecta tu asistente de IA [#conecta-tu-asistente-de-ia]
Añade el MCP de documentación de SMSPVA a tu cliente de IA para consultar métodos y obtener ejemplos mientras trabajas. SMSPVA aloja el servidor. No necesitas descargar el proyecto, instalar Node.js o Docker, ni proporcionar una clave API de SMSPVA.
Copia esta URL exacta en un cliente compatible con MCP remoto mediante **Streamable HTTP**:
```text
https://mcp.smspva.com/docs
```
| Ajuste | Valor |
| --- | --- |
| Nombre del servidor | **`smspva_docs`** |
| Transporte | **Streamable HTTP**; algunos clientes lo llaman **HTTP** |
| URL del servidor | **`https://mcp.smspva.com/docs`** |
| Autenticación | Ninguna; sin clave API ni inicio de sesión OAuth |
| Idiomas de la documentación | English **`en`**, español **`es`**, 中文 **`zh`** |
En los ajustes MCP de tu cliente, añade un servidor remoto con estos valores, guarda la configuración y actívalo o vuelve a conectarlo. Revisa cualquier solicitud de confianza antes de autorizar la conexión. Integra los ejemplos siguientes en tu configuración existente sin sustituir otros servidores.
Este MCP busca y lee documentación pública y devuelve ejemplos. No puede comprar números, leer tus SMS o correos privados ni modificar tu cuenta. El MCP de la API es independiente y se describe más adelante. Alternative API queda excluida de ambos.
## Codex [#codex]
Añade esta entrada a **`config.toml`** de Codex. Si ya tienes **`mcp_servers.smspva_docs`** conectado a un proceso local, sustituye esa entrada por la configuración con URL; no dupliques la tabla. Conserva cualquier conexión independiente **`mcp_servers.smspva`** para la API.
```toml
[mcp_servers.smspva_docs]
url = "https://mcp.smspva.com/docs"
startup_timeout_sec = 20
tool_timeout_sec = 45
```
Vuelve a conectar el servidor o reinicia la sesión de Codex para aplicar el cambio. Esta entrada no necesita **`command`**, **`args`**, **`env`** ni token. Consulta la [guía oficial de MCP para Codex](https://learn.chatgpt.com/docs/extend/mcp?surface=cli) para conocer las ubicaciones de configuración y los controles del cliente.
## Cursor [#cursor]
Añade esta entrada a **`.cursor/mcp.json`** en tu proyecto, o a **`~/.cursor/mcp.json`** para tu configuración de usuario:
```json
{
"mcpServers": {
"smspva_docs": {
"url": "https://mcp.smspva.com/docs"
}
}
}
```
Activa el servidor en los ajustes MCP de Cursor. Consulta la [guía oficial de MCP para Cursor](https://prod.cursor.com/docs/mcp).
## VS Code [#vs-code]
Ejecuta **MCP: Add Server** desde la paleta de comandos, elige **HTTP**, introduce **`https://mcp.smspva.com/docs`** y usa **`smspva_docs`** como identificador. Elige dónde guardar la configuración y revisa la solicitud de confianza. Para **`.vscode/mcp.json`** en el espacio de trabajo, la configuración equivalente es:
```json
{
"servers": {
"smspva_docs": {
"type": "http",
"url": "https://mcp.smspva.com/docs"
}
}
}
```
El formato puede depender del proveedor del agente seleccionado. Consulta la [guía de VS Code](https://code.visualstudio.com/docs/agent-customization/mcp-servers) y la [referencia de configuración](https://code.visualstudio.com/docs/agents/reference/mcp-configuration).
## Pruébalo en una conversación [#pruébalo-en-una-conversación]
Una vez conectado, pide a tu asistente que utilice el MCP de documentación de SMSPVA. Por ejemplo:
- «Usa el MCP de documentación de SMSPVA para mostrar un ejemplo en Python que consulte mi saldo. Explícalo en español y no lo ejecutes».
- «Busca el método de proveedores de Private Email en la documentación en español y devuelve su ejemplo de solicitud en JavaScript».
- «Lee el flujo de Rental en chino y explica cómo funcionan la activación y la consulta de mensajes».
Una conexión correcta muestra cuatro herramientas: **`smspva_docs_search`**, **`smspva_docs_read_page`**, **`smspva_docs_get_examples`** y **`smspva_docs_list_pages`**. Si tu asistente no las ve, comprueba que el servidor esté activado en la sesión y que tu organización permita la conexión.
El servicio contiene 228 páginas, 76 por idioma, y cubre los 56 métodos aprobados. SMSPVA mantiene el paquete de documentación alojado; los usuarios no tienen que recompilarlo. Cada resultado identifica su versión de la documentación. Los precios y la disponibilidad actuales siguen consultándose mediante las API o las listas dinámicas de este sitio.
## Si no puedes conectar [#si-no-puedes-conectar]
- Usa la URL completa **`https://mcp.smspva.com/docs`**, incluido **`/docs`**. No la sustituyas por la página principal ni añadas **`/sse`**.
- Un **`405`** al abrir **`/docs`** en el navegador puede ser normal: es un endpoint del protocolo, no una página web. Comprueba la conexión desde un cliente MCP.
- Un **`403`** en un cliente que funciona dentro del navegador puede indicar que su **`Origin`** no está permitido. El comodín de CORS no evita las comprobaciones de Origin del servicio. Usa un cliente nativo o contacta con soporte de SMSPVA indicando el cliente y el error exacto.
- Si recibes **`429`**, espera antes de reintentar. Ante un timeout o **`503`**, vuelve a conectar más tarde y revisa la red y las políticas de tu organización. Añadir repetidamente el mismo servidor no resuelve estos errores.
- No envíes tu clave de SMSPVA a este endpoint de documentación. La conexión no requiere compras, acceso a tu cuenta ni permiso para ejecutar ejemplos.
## Buscar, leer y obtener ejemplos [#buscar-leer-y-obtener-ejemplos]
Indica **`locale`** explícitamente: **`en`**, **`es`** o **`zh`**. El servidor usa las páginas y los ejemplos de ese idioma; no cambia de idioma en silencio ni traduce el código. Los identificadores de página coinciden en los tres idiomas, por ejemplo **`api/balance`**, **`rental/default-services`**, **`email/providers`**, **`sdks`** e **`index`**.
| Herramienta | Para qué sirve |
| --- | --- |
| **`smspva_docs_search`** | Busca una **`query`** en el **`locale`** elegido; permite filtrar por **`section`** y definir **`limit`** |
| **`smspva_docs_read_page`** | Lee una **`page`** en Markdown, con **`offset`** y **`max_chars`** para páginas largas |
| **`smspva_docs_get_examples`** | Obtiene bloques de código completos de una **`page`**; filtra por **`language`** o **`kind`** y pagina con **`offset`** y **`limit`** |
| **`smspva_docs_list_pages`** | Explora los identificadores de página de un **`locale`**, con **`section`** opcional, **`offset`** y **`limit`** |
Los valores de **`section`** son **`activation`**, **`rental`**, **`email`** y **`guides`**. Para ejemplos de solicitudes, elige **`language`** entre **`curl`**, **`javascript`**, **`typescript`**, **`python`**, **`php`**, **`go`**, **`csharp`** y **`java`**. También hay otros bloques, como respuestas JSON y comandos de preparación de shell. **`kind`** distingue ejemplos **`request`**, **`response`** y **`guide`**.
Estos son argumentos de solicitudes MCP **`tools/call`**. Busca en la referencia de Activation en español:
```json
{
"name": "smspva_docs_search",
"arguments": {"query": "saldo", "locale": "es", "section": "activation", "limit": 5}
}
```
Lee la página de saldo en chino:
```json
{
"name": "smspva_docs_read_page",
"arguments": {"page": "api/balance", "locale": "zh", "max_chars": 6000}
}
```
Obtén la solicitud Python de la página en inglés:
```json
{
"name": "smspva_docs_get_examples",
"arguments": {"page": "api/balance", "locale": "en", "language": "python", "kind": "request", "limit": 1}
}
```
Los bloques de código proceden directamente de la página elegida. Se mantienen los métodos HTTP, los nombres de parámetros, los códigos de respuesta y el sentido de las advertencias importantes. Para continuar con una página larga o más ejemplos, usa la información de paginación del resultado.
## MCP de la API: trabajar con SMSPVA [#mcp-de-la-api-trabajar-con-smspva]
La versión alfa local ofrece los 56 métodos de Activation V2, Rental y Private Email como herramientas MCP. Funciona con Node.js 22.16 o posterior y se conecta a tu cliente MCP mediante stdio. No necesita Docker.
Esta versión se ejecuta como proceso local. Todavía no tiene un endpoint HTTP remoto ni OAuth, y no se ha publicado en un registro de paquetes, GitHub o directorio MCP. Alternative API queda excluida.
## Compilar y conectar el servidor de la API [#compilar-y-conectar-el-servidor-de-la-api]
Desde el directorio del proyecto:
```sh
cd sdk/javascript
npm ci
cd ../../mcp
npm ci
npm run build
```
Añade el servidor a la configuración MCP de tu cliente. Sustituye la ruta absoluta por la ubicación de **`mcp/src/cli.mjs`** en tu equipo:
```json
{
"mcpServers": {
"smspva": {
"command": "node",
"args": ["/absolute/path/to/mcp/src/cli.mjs"],
"env": {
"SMSPVA_API_KEY": "YOUR_API_KEY",
"SMSPVA_READ_ONLY": "true"
}
}
}
}
```
Guarda la **`SMSPVA_API_KEY`** real en el almacén de secretos del cliente o en una configuración local privada. No la pegues en un chat ni en los argumentos de una herramienta. Los métodos públicos funcionan sin clave; un método protegido devuelve un error de validación si no hay una clave configurada.
El ejemplo activa **`SMSPVA_READ_ONLY`** y expone 36 herramientas de solo lectura. En este modo, el servidor también rechaza las llamadas a las otras 20 herramientas, aunque el cliente conozca sus nombres. Para habilitar las 56, omite esta opción o establece **`false`**. Sin esta opción, las 56 están disponibles por defecto.
## Codex: servidor de la API [#codex-servidor-de-la-api]
Usa este ejemplo en **`config.toml`** de Codex con Node.js 22.16+. Define **`SMSPVA_API_KEY`** en su entorno antes de iniciar Codex. El ejemplo no instala el servidor. Consulta la [documentación oficial de OpenAI](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).
```toml
[mcp_servers.smspva]
command = "node"
args = ["/absolute/path/to/mcp/src/cli.mjs"]
env_vars = ["SMSPVA_API_KEY"]
startup_timeout_sec = 20
tool_timeout_sec = 45
[mcp_servers.smspva.env]
SMSPVA_READ_ONLY = "true"
```
## Llamar a una herramienta [#llamar-a-una-herramienta]
Los nombres siguen el formato **`smspva__`**. La familia es **`activation`**, **`rental`** o **`email`**. Los parámetros conservan los nombres de la referencia de la API. Las consultas de países, servicios, proveedores, precios y disponibilidad obtienen datos actuales de la API; no usan listas incluidas en el paquete.
Estos son los argumentos de una solicitud MCP **`tools/call`**. Para consultar el saldo de tu cuenta:
```json
{
"name": "smspva_activation_get_balance",
"arguments": {}
}
```
Para obtener los proveedores de Email actuales sin enviar una clave de API:
```json
{
"name": "smspva_email_get_providers",
"arguments": {}
}
```
Leer un SMS recién recibido puede generar un cargo. La siguiente llamada solo está disponible con el modo de solo lectura desactivado. Usa un **`orderid`** existente de tu cuenta y ejecútala solo cuando quieras recuperar ese resultado:
```json
{
"name": "smspva_activation_receive_sms",
"arguments": {
"orderid": 12345
}
}
```
El servidor realiza una solicitud a la API por llamada. No crea pedidos por su cuenta, no reintenta solicitudes ni consulta mensajes en segundo plano. Lee el [flujo de Activation](/es/docs/activation-workflow) antes de programar consultas repetidas de SMS en tu cliente.
## Resultados, errores y cargos [#resultados-errores-y-cargos]
Las herramientas que terminan correctamente devuelven la respuesta original de la API en **`structuredContent`**. HTTP **`202`** con **`SMS_NOT_YET_RECEIVED`** sigue siendo un resultado normal de espera. La creación de Email con **`status=2`** sigue siendo un resultado normal sin disponibilidad. Los métodos, parámetros, códigos y tipos de los valores conservan los contratos documentados.
Tu cliente MCP también puede leer los contratos OpenAPI incluidos mediante **`smspva://contracts/activation`**, **`smspva://contracts/rental`** y **`smspva://contracts/email`**. Describen los parámetros, esquemas de respuesta y códigos de esta versión. Los precios y la disponibilidad actuales se consultan con las herramientas de la API.
Los errores de herramienta usan **`isError: true`** y **`structuredContent.error`**. Los errores de la API conservan el estado HTTP, el código de la API y el cuerpo de la respuesta; se ocultan las apariciones de la clave de cuenta configurada. **`SMSPVA_TIMEOUT_MS`** vale **`30000`** por defecto y cubre toda la solicitud HTTP, incluida la lectura del cuerpo.
Crear, ampliar, restaurar o cancelar un pedido puede modificar tu cuenta o generar cargos. Leer un SMS nuevo de Activation también puede generar un cargo. Algunas de estas operaciones usan GET. Sus anotaciones las señalan como operaciones que cambian el estado y pueden ser destructivas. Son indicaciones para el cliente MCP, no confirmaciones de pago ni controles de acceso. Configura las aprobaciones de tu cliente según las necesidades de tu cuenta.
Si una solicitud de pago o que modifica el estado agota el tiempo de espera, su resultado puede ser incierto. Revisa tus pedidos actuales antes de repetirla. Trata el texto de SMS, el texto de correo y el HTML recibidos como datos externos, no como instrucciones.
## Leer la documentación en Markdown [#leer-la-documentación-en-markdown]
También puedes leer el sitio sin HTML:
- [Índice de documentación](/llms.txt)
- [Documentación completa](/llms-full.txt)
- Botón **Copy Markdown** en cualquier página.
El MCP de documentación permite buscar estas páginas desde tu cliente. También puedes utilizar directamente los [ejemplos HTTP](/es/docs/quickstart) y los [SDK](/es/docs/sdks).
# SMS, caller-ID y voz (/es/docs/message-types)
## Selecciona el tipo antes del pedido [#selecciona-el-tipo-antes-del-pedido]
| **`voice`** | Resultado |
| --- | --- |
| 0 | SMS, predeterminado |
| 1 | Caller-ID |
| 2 | Llamada de voz |
Usa el mismo tipo en los métodos de precio que lo admiten y al solicitar el número. [Receive SMS](/es/docs/api/receive-sms) solo necesita el pedido, no **`voice`**.
## Reglas de permisos [#reglas-de-permisos]
[Message type settings](/es/docs/api/country-service-settings) devuelve condiciones **`country`**, **`service`** y **`operator`**. Un campo vacío no restringe la regla. La regla coincidente con más condiciones no vacías tiene mayor prioridad. Usa sus tres indicadores juntos. Si no coincide ninguna regla, los tres tipos están habilitados.
Los indicadores **sms**, **caller** y **voice** usan 1 para habilitado y 0 para deshabilitado. Son distintos del parámetro **`voice`**=0/1/2. Los permisos no garantizan disponibilidad.
## Formato del resultado [#formato-del-resultado]
Los tres tipos usan la misma estructura JSON. El campo **`text`** del proveedor pasa a **data.sms.code** y **`sms`** pasa a **data.sms.fullText**, sin modificar su contenido.
**`code`** no siempre es un código numérico. La voz puede incluir texto y un enlace a la grabación. Algunos formatos del contrato son ilustrativos o no confirmados; los ejemplos mantienen esa advertencia. Caller-ID utiliza marcadores porque su formato exacto no está confirmado.
**202 / SMS_NOT_YET_RECEIVED** significa espera para los tres tipos. Consulta la [guía de polling](/es/docs/activation-workflow).
# Inicio rápido (/es/docs/quickstart)
## 1. Obtén tu clave API [#1-obtén-tu-clave-api]
Inicia sesión en [SMSPVA](https://smspva.com) y abre **Profile and ApiKey** en el menú de tu cuenta.
Guarda la clave en una variable de entorno del servidor para que tu aplicación la lea sin incluirla en el código fuente. No la expongas en el navegador ni en repositorios públicos.
```bash
export SMSPVA_API_KEY="YOUR_API_KEY"
```
```powershell
$env:SMSPVA_API_KEY = "YOUR_API_KEY"
```
## 2. Consulta tu saldo [#2-consulta-tu-saldo]
Activation V2 usa **https://api.smspva.com** y la cabecera **apikey**. El ejemplo cURL requiere un shell POSIX (macOS, Linux o WSL). En Windows, JavaScript y Python también funcionan desde PowerShell. JavaScript requiere Node.js 22.16+; Python utiliza la biblioteca estándar (3.10+).
```bash
curl --fail-with-body --max-time 30 \
'https://api.smspva.com/activation/balance' \
--header "apikey: $SMSPVA_API_KEY"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
if (!apiKey) throw new Error("Set SMSPVA_API_KEY first");
const response = await fetch(
"https://api.smspva.com/activation/balance",
{
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
},
);
const result = await response.json();
if (!response.ok || result.error || result.statusCode !== 200) {
throw new Error(
result.error?.description ?? `Request failed: ${response.status}`,
);
}
// The API returns balance as a string. Keep it for display.
console.log(result.data.balance);
```
```python
import json
import os
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen
api_key = os.environ["SMSPVA_API_KEY"]
request = Request(
"https://api.smspva.com/activation/balance",
headers={"apikey": api_key},
)
try:
with urlopen(request, timeout=30) as response:
result = json.load(response)
except HTTPError as error:
# HTTPError is also a readable response.
detail = error.read().decode("utf-8", errors="replace")
raise RuntimeError(f"HTTP {error.code}: {detail}") from error
except (URLError, TimeoutError) as error:
raise RuntimeError("Request could not be completed") from error
if result.get("error") or result.get("statusCode") != 200:
raise RuntimeError(result.get("error", result))
print(result["data"]["balance"])
```
## 3. Interpreta la respuesta [#3-interpreta-la-respuesta]
```json
{
"statusCode": 200,
"data": { "balance": "10.50" }
}
```
Tu respuesta mostrará el saldo de tu cuenta. **`balance`** es una **cadena de texto**; consérvala al mostrar el importe. Antes de usar **`data`**, comprueba la respuesta HTTP y los errores de la API.
Una clave ausente o de longitud incorrecta devuelve HTTP **400** con **`APIKEY_NOT_SET`**. Si la solicitud agota el tiempo de espera, todavía no tienes un resultado confirmado.
## Siguientes pasos [#siguientes-pasos]
Consulta la [referencia del saldo](/es/docs/api/balance), el [plan de SDKs](/es/docs/sdks) o [MCP y Markdown](/es/docs/mcp).
Continúa con el [flujo de activación](/es/docs/activation-workflow), la [referencia completa](/es/docs/api) y los [ejemplos en ocho lenguajes](/es/docs/examples). No repitas automáticamente una compra tras un fallo de conexión: la primera solicitud podría haberse completado.
# Países y servicios (/es/docs/reference-data)
Elige los códigos de **`country`** y **`service`** de estas listas para Activation V2. Comprueba los precios y la disponibilidad antes de pedir un número.
Las listas se cargan al abrir la página y se actualizan cada **cinco minutos** mientras está visible. La fuente también tiene cinco minutos de caché, por lo que los cambios pueden tardar un poco en aparecer. Los alquileres de números y de correo tienen sus propias listas.
## Guías relacionadas [#guías-relacionadas]
- [Datos de referencia](/es/docs/api/operators)
- [Disponibilidad](/es/docs/api/country-countnumbers)
- [Precios](/es/docs/api/service-price)
[JSON actualizado](/reference-data.php)
# Activar alquiler (/es/docs/rental/activate)
GET{"https://smspva.com/api/rent.php?method=activate"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "activate" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`id`** | query | integer | Sí | 1 | ID del pedido |
## Cómo usar este método [#cómo-usar-este-método]
Activa el alquiler antes de enviar un SMS a su número. Usa el ID de [Pedidos de alquiler](/es/docs/rental/orders) y comprueba allí su **`state`**. Cuando esté activo, lee los mensajes con [SMS del alquiler](/es/docs/rental/sms).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=activate" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "activate",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "activate",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "activate",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'activate',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "activate")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "activate",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "activate");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": [
{
"id": 123
}
]
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | array<object> | |
| **`data[].id`** | integer | ID del pedido |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Añadir servicio al pedido (/es/docs/rental/add-service)
GET{"https://smspva.com/api/rent.php?method=add_service_to_order"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "add_service_to_order" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`id`** | query | integer | Sí | 56547 | ID del pedido |
| **`service`** | query | string | Sí | "opt89" | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`pnumber`** | query | string | Sí | "79335445295" | Número alquilado con prefijo de país, sin el signo +. |
| **`rent_days`** | query | integer | No | 7 | Días opcionales de alquiler. Si se omiten, se usan 7 días en la mayoría de países y 1 día en Canadá. |
## Cómo usar este método [#cómo-usar-este-método]
Añade un servicio a un alquiler existente. Obtén su ID y **`pnumber`** en [Pedidos de alquiler](/es/docs/rental/orders) y consulta el servicio y precio en [Datos por proveedor](/es/docs/rental/data-by-provider) para ese país.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
- **`SMSPVA_RENTAL_NUMBER`**: **`pnumber`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
: "${SMSPVA_RENTAL_NUMBER:?Set SMSPVA_RENTAL_NUMBER}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=add_service_to_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID" \
--data-urlencode "service=opt89" \
--data-urlencode "pnumber=$SMSPVA_RENTAL_NUMBER" \
--data-urlencode "rent_days=7"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt89";
const pnumber = required("SMSPVA_RENTAL_NUMBER");
const rent_days = process.env.SMSPVA_RENTAL_RENT_DAYS ?? "7";
const query = new URLSearchParams({
"method": "add_service_to_order",
"id": id,
"service": service,
"pnumber": pnumber,
"rent_days": rent_days
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt89";
const pnumber = required("SMSPVA_RENTAL_NUMBER");
const rent_days = process.env.SMSPVA_RENTAL_RENT_DAYS ?? "7";
const query = new URLSearchParams({
"method": "add_service_to_order",
"id": id,
"service": service,
"pnumber": pnumber,
"rent_days": rent_days
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
service = os.environ.get("SMSPVA_RENTAL_SERVICE", "opt89")
pnumber = os.environ["SMSPVA_RENTAL_NUMBER"]
rent_days = os.environ.get("SMSPVA_RENTAL_RENT_DAYS", "7")
query = {
"method": "add_service_to_order",
"id": id,
"service": service,
"pnumber": pnumber,
"rent_days": rent_days
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'add_service_to_order',
'id' => $id,
'service' => $service,
'pnumber' => $pnumber,
'rent_days' => $rent_days
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
service := env("SMSPVA_RENTAL_SERVICE", "opt89")
pnumber := env("SMSPVA_RENTAL_NUMBER", "")
rent_days := env("SMSPVA_RENTAL_RENT_DAYS", "7")
query := url.Values{}
query.Set("method", "add_service_to_order")
query.Set("id", id)
query.Set("service", service)
query.Set("pnumber", pnumber)
query.Set("rent_days", rent_days)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var service = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICE") ?? "opt89";
var pnumber = Required("SMSPVA_RENTAL_NUMBER");
var rent_days = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_RENT_DAYS") ?? "7";
var query = new Dictionary {
["method"] = "add_service_to_order",
["id"] = id,
["service"] = service,
["pnumber"] = pnumber,
["rent_days"] = rent_days
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
String service = env("SMSPVA_RENTAL_SERVICE", "opt89");
String pnumber = env("SMSPVA_RENTAL_NUMBER", null);
String rent_days = env("SMSPVA_RENTAL_RENT_DAYS", "7");
Map query = new LinkedHashMap<>();
query.put("method", "add_service_to_order");
query.put("id", id);
query.put("service", service);
query.put("pnumber", pnumber);
query.put("rent_days", rent_days);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"id": 4211321,
"pnumber": "37067181111",
"service": "opt95",
"until": 1771583220
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | Detalles del servicio añadido |
| **`data.id`** | integer | ID del pedido |
| **`data.pnumber`** | string | Número de teléfono |
| **`data.service`** | string | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`data.until`** | integer | Vencimiento del servicio (timestamp Unix) |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Días PayPal Canadá (/es/docs/rental/canada-paypal-days)
GET{"https://smspva.com/api/rent.php?method=get_days_canada_paypal"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Puedes llamar a este método sin clave API.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "get_days_canada_paypal" | Nombre del método |
## Cómo usar este método [#cómo-usar-este-método]
Consulta las opciones de días de alquiler del flujo de PayPal en Canadá.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_days_canada_paypal"
```
```js
const query = new URLSearchParams({
"method": "get_days_canada_paypal"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const query = new URLSearchParams({
"method": "get_days_canada_paypal"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
query = {
"method": "get_days_canada_paypal"
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_days_canada_paypal'
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
query := url.Values{}
query.Set("method", "get_days_canada_paypal")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var query = new Dictionary {
["method"] = "get_days_canada_paypal"
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
Map query = new LinkedHashMap<>();
query.put("method", "get_days_canada_paypal");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": [
{
"Days": 30,
"Amount": 10
}
]
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | array<object> | Opciones de duración del flujo PayPal Canadá. |
| **`data[].Days`** | integer | Duración del alquiler en días. |
| **`data[].Amount`** | integer | Importe asociado al período, tal como lo devuelve la API. |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Disponibilidad de números (/es/docs/rental/count)
GET{"https://smspva.com/api/rent.php?method=getcount"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Puedes llamar a este método sin clave API.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "getcount" | Nombre del método |
| **`country`** | query | string | Sí | "KZ" | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`dtype`** | query | string | No | "week" | Unidad del período: week o month. Si se omite, se usa week. |
| **`dcount`** | query | integer | No | 1 | Número de períodos; con **`dtype`**=week, número de semanas. Si se omite, se usa 1. |
## Cómo usar este método [#cómo-usar-este-método]
Consulta los números disponibles para alquilar en un **`country`**. Si los omites, **`dtype`** usa **`week`** y **`dcount`** usa **1**. Los nombres y precios están en [Datos de alquiler](/es/docs/rental/data); el desglose, en [Disponibilidad por proveedor](/es/docs/rental/counts-by-provider).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getcount" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getcount",
"country": country,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getcount",
"country": country,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getcount",
"country": country,
"dtype": dtype,
"dcount": dcount
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getcount',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getcount")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getcount",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getcount");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | oneOf | Disponibilidad por servicio o total, según la respuesta del servidor. |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Países por servicio (/es/docs/rental/countries-by-service)
GET{"https://smspva.com/api/rent.php?method=get_country_by_service"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Puedes llamar a este método sin clave API.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "get_country_by_service" | Nombre del método |
| **`service`** | query | string | Sí | "opt20" | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`dtype`** | query | string | Sí | "week" | Unidad del período: week o month |
| **`dcount`** | query | integer | No | 1 | Número de períodos; con **`dtype`**=week, número de semanas. Si se omite, se usa 1. |
## Cómo usar este método [#cómo-usar-este-método]
Busca países para el **`service`** y el **`dtype`** de tu alquiler. Después compara los proveedores en [Datos por proveedor](/es/docs/rental/data-by-provider), manteniendo el mismo servicio y duración.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_country_by_service" \
--data-urlencode "service=opt20" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt20";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "get_country_by_service",
"service": service,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt20";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "get_country_by_service",
"service": service,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
service = os.environ.get("SMSPVA_RENTAL_SERVICE", "opt20")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "get_country_by_service",
"service": service,
"dtype": dtype,
"dcount": dcount
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_country_by_service',
'service' => $service,
'dtype' => $dtype,
'dcount' => $dcount
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
service := env("SMSPVA_RENTAL_SERVICE", "opt20")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "get_country_by_service")
query.Set("service", service)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var service = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICE") ?? "opt20";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "get_country_by_service",
["service"] = service,
["dtype"] = dtype,
["dcount"] = dcount
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String service = env("SMSPVA_RENTAL_SERVICE", "opt20");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "get_country_by_service");
query.put("service", service);
query.put("dtype", dtype);
query.put("dcount", dcount);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"": {
"service_name": "Fiverr",
"price": "0.20",
"procent_days": "30",
"procent": "30",
"day_step": "0.00",
"country": "KZ",
"phoneAmount": 79
}
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | |
| **`data.*`** | object | |
| **`data.*.service_name`** | string | |
| **`data.*.price`** | string | |
| **`data.*.procent_days`** | string | |
| **`data.*.procent`** | string | |
| **`data.*.day_step`** | string | |
| **`data.*.country`** | string | |
| **`data.*.phoneAmount`** | integer | |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Países de alquiler (/es/docs/rental/countries)
GET{"https://smspva.com/api/rent.php?method=getcountries"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Puedes llamar a este método sin clave API.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "getcountries" | Nombre del método |
## Cómo usar este método [#cómo-usar-este-método]
Consulta los países disponibles para alquilar números. Usa el código devuelto en [Datos de alquiler](/es/docs/rental/data) o [Datos por proveedor](/es/docs/rental/data-by-provider) para ver servicios, precios y disponibilidad.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getcountries"
```
```js
const query = new URLSearchParams({
"method": "getcountries"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const query = new URLSearchParams({
"method": "getcountries"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
query = {
"method": "getcountries"
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getcountries'
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
query := url.Values{}
query.Set("method", "getcountries")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var query = new Dictionary {
["method"] = "getcountries"
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
Map query = new LinkedHashMap<>();
query.put("method", "getcountries");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": [
{
"name": "United States",
"code": "US",
"url_country_name": "united-states",
"rent_switch_type": "FAST",
"rent_avail_prolong": "1"
}
]
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | |
| **`data`** | array<object> | |
| **`data[].name`** | string | Nombre del país |
| **`data[].code`** | string | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`data[].url_country_name`** | string | Identificador del país usado en las URL públicas. |
| **`data[].rent_switch_type`** | string | Modalidad de disponibilidad del alquiler en ese país. |
| **`data[].rent_avail_prolong`** | string | Indica si se permiten ampliaciones en ese país. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Disponibilidad por proveedor (/es/docs/rental/counts-by-provider)
GET{"https://smspva.com/api/rent.php?method=getCountWithProviders"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
**apikey** es opcional. Omítelo para datos públicos o envíalo para datos y precios personalizados según el contrato.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "getCountWithProviders" | Nombre del método |
| **`apikey`** | query | string | No | (optional) | Clave API opcional; permite obtener datos personalizados. |
| **`country`** | query | string | Sí | "KZ" | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`dtype`** | query | string | No | "week" | Unidad del período: week o month. Si se omite, se usa week. |
| **`dcount`** | query | integer | No | 1 | Número de períodos; con **`dtype`**=week, número de semanas. Si se omite, se usa 1. |
## Cómo usar este método [#cómo-usar-este-método]
Compara la disponibilidad por servicio y proveedor. Para cada código de servicio, **`Amount`** relaciona proveedores con cantidades y **`Total`** muestra la suma. Lee esas claves de la respuesta, porque pueden cambiar.
Comprueba **`status`** incluso con HTTP **200**. Si vale **0**, el error está en **`msg`**.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
# Optional: add --data-urlencode "apikey=$SMSPVA_API_KEY" for account-specific data.
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getCountWithProviders" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getCountWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getCountWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ.get("SMSPVA_API_KEY")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getCountWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getCountWithProviders',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := os.Getenv("SMSPVA_API_KEY")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getCountWithProviders")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getCountWithProviders",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", "");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getCountWithProviders");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"opt48": {
"Amount": {
"Limbo_AT": 12,
"Tele2_AT": 1,
"yesss_AT": 69
},
"Total": 82
}
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | Cantidades por proveedor y total para cada código de servicio. |
| **`data.*`** | object | |
| **`data.*.Amount`** | object | Cantidad de números disponibles por proveedor. |
| **`data.*.Amount.*`** | integer | |
| **`data.*.Total`** | integer | Total de números disponibles para el servicio. |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Crear alquiler multiservicio (/es/docs/rental/create-multi)
GET{"https://smspva.com/api/rent.php?method=create_multi"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "create_multi" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`dtype`** | query | string | Sí | "week" | Unidad del período: week o month |
| **`dcount`** | query | integer | Sí | 1 | Número de períodos; si **`dtype`**=week, es el número de semanas. |
| **`country`** | query | string | Sí | "KZ" | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`services`** | query | string | Sí | "opt6,opt7,opt8" | Códigos de servicio separados por comas. [Lista de servicios](/es/docs/rental/reference-data) |
| **`provider`** | query | string | No | "T-Mobile" | Proveedor opcional. Si lo omites, se elige uno al azar entre los disponibles. |
| **`partner_key`** | query | string | No | "partnerkeyhere" | Clave de socio opcional para referidos. |
## Cómo usar este método [#cómo-usar-este-método]
Alquila un número para varios servicios. Envía los códigos separados por comas en **`services`** y consulta antes la [disponibilidad multiservicio](/es/docs/rental/multi-service-count).
Elige un [país](/es/docs/rental/countries) y compara [servicios, proveedores y precios](/es/docs/rental/data-by-provider) con la misma duración. Busca el alquiler creado en [Pedidos de alquiler](/es/docs/rental/orders) y [actívalo](/es/docs/rental/activate) antes de enviar un SMS.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=create_multi" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1" \
--data-urlencode "country=KZ" \
--data-urlencode "services=opt6,opt7,opt8"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt6,opt7,opt8";
const query = new URLSearchParams({
"method": "create_multi",
"dtype": dtype,
"dcount": dcount,
"country": country,
"services": services
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt6,opt7,opt8";
const query = new URLSearchParams({
"method": "create_multi",
"dtype": dtype,
"dcount": dcount,
"country": country,
"services": services
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
services = os.environ.get("SMSPVA_RENTAL_SERVICES", "opt6,opt7,opt8")
query = {
"method": "create_multi",
"dtype": dtype,
"dcount": dcount,
"country": country,
"services": services
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'create_multi',
'dtype' => $dtype,
'dcount' => $dcount,
'country' => $country,
'services' => $services
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
services := env("SMSPVA_RENTAL_SERVICES", "opt6,opt7,opt8")
query := url.Values{}
query.Set("method", "create_multi")
query.Set("dtype", dtype)
query.Set("dcount", dcount)
query.Set("country", country)
query.Set("services", services)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var services = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICES") ?? "opt6,opt7,opt8";
var query = new Dictionary {
["method"] = "create_multi",
["dtype"] = dtype,
["dcount"] = dcount,
["country"] = country,
["services"] = services
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String services = env("SMSPVA_RENTAL_SERVICES", "opt6,opt7,opt8");
Map query = new LinkedHashMap<>();
query.put("method", "create_multi");
query.put("dtype", dtype);
query.put("dcount", dcount);
query.put("country", country);
query.put("services", services);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"id": 40370,
"pnumber": "9096037108",
"ccode": "+7",
"service": "opt6",
"until": "1587633960"
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | |
| **`data.id`** | integer | ID del pedido |
| **`data.pnumber`** | string | Número sin prefijo de país |
| **`data.ccode`** | string | Código numérico de país |
| **`data.service`** | string | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`data.until`** | string | Fecha de vencimiento (timestamp Unix) |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Crear alquiler (/es/docs/rental/create)
GET{"https://smspva.com/api/rent.php?method=create"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "create" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`dtype`** | query | string | Sí | "week" | Unidad del período: week o month |
| **`dcount`** | query | integer | Sí | 1 | Número de períodos; si **`dtype`**=week, es el número de semanas. |
| **`country`** | query | string | Sí | "KZ" | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`service`** | query | string | Sí | "opt6" | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`provider`** | query | string | No | "T-Mobile" | Proveedor opcional. Si lo omites, se elige uno al azar entre los disponibles. |
| **`partner_key`** | query | string | No | "partnerkeyhere" | Clave de socio opcional para referidos. |
## Cómo usar este método [#cómo-usar-este-método]
Alquila un número para un servicio. Para varios servicios en el mismo número, usa [Crear alquiler multiservicio](/es/docs/rental/create-multi) tras comprobar la [disponibilidad](/es/docs/rental/multi-service-count).
Elige un [país](/es/docs/rental/countries) y compara [servicios, proveedores y precios](/es/docs/rental/data-by-provider) con la misma duración. Busca el alquiler creado en [Pedidos de alquiler](/es/docs/rental/orders) y [actívalo](/es/docs/rental/activate) antes de enviar un SMS.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=create" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1" \
--data-urlencode "country=KZ" \
--data-urlencode "service=opt6"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt6";
const query = new URLSearchParams({
"method": "create",
"dtype": dtype,
"dcount": dcount,
"country": country,
"service": service
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt6";
const query = new URLSearchParams({
"method": "create",
"dtype": dtype,
"dcount": dcount,
"country": country,
"service": service
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
service = os.environ.get("SMSPVA_RENTAL_SERVICE", "opt6")
query = {
"method": "create",
"dtype": dtype,
"dcount": dcount,
"country": country,
"service": service
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'create',
'dtype' => $dtype,
'dcount' => $dcount,
'country' => $country,
'service' => $service
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
service := env("SMSPVA_RENTAL_SERVICE", "opt6")
query := url.Values{}
query.Set("method", "create")
query.Set("dtype", dtype)
query.Set("dcount", dcount)
query.Set("country", country)
query.Set("service", service)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var service = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICE") ?? "opt6";
var query = new Dictionary {
["method"] = "create",
["dtype"] = dtype,
["dcount"] = dcount,
["country"] = country,
["service"] = service
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String service = env("SMSPVA_RENTAL_SERVICE", "opt6");
Map query = new LinkedHashMap<>();
query.put("method", "create");
query.put("dtype", dtype);
query.put("dcount", dcount);
query.put("country", country);
query.put("service", service);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"id": 40370,
"pnumber": "9096037108",
"ccode": "+7",
"service": "opt6",
"until": "1587633960"
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | |
| **`data.id`** | integer | ID del pedido |
| **`data.pnumber`** | string | Número sin prefijo de país |
| **`data.ccode`** | string | Código numérico de país |
| **`data.service`** | string | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`data.until`** | string | Fecha de vencimiento (timestamp Unix) |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Datos por proveedor (/es/docs/rental/data-by-provider)
GET{"https://smspva.com/api/rent.php?method=getdataWithProviders"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
**apikey** es opcional. Omítelo para datos públicos o envíalo para datos y precios personalizados según el contrato.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "getdataWithProviders" | Nombre del método |
| **`apikey`** | query | string | No | (optional) | Clave API opcional; permite obtener datos y precios personalizados. |
| **`country`** | query | string | Sí | "KZ" | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`dtype`** | query | string | No | "week" | Unidad del período: week o month. Si se omite, se usa week. |
| **`dcount`** | query | integer | No | 1 | Número de períodos; con **`dtype`**=week, número de semanas. Si se omite, se usa 1. |
| **`extend`** | query | string | No | "1" | Activa el formato de respuesta ampliado. |
## Cómo usar este método [#cómo-usar-este-método]
Compara los servicios de un **`country`**, sus precios diarios y los proveedores disponibles. Usa el mismo **`dtype`** y **`dcount`** que tendrá el alquiler.
Elige el país en [Países de alquiler](/es/docs/rental/countries) y usa el código del servicio en [Crear alquiler](/es/docs/rental/create) o [Crear alquiler multiservicio](/es/docs/rental/create-multi).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
# Optional: add --data-urlencode "apikey=$SMSPVA_API_KEY" for account-specific data.
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getdataWithProviders" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdataWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdataWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ.get("SMSPVA_API_KEY")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getdataWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getdataWithProviders',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := os.Getenv("SMSPVA_API_KEY")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getdataWithProviders")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getdataWithProviders",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", "");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getdataWithProviders");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"services": [
{
"name": "1cupis & okcupid & winline",
"service": "opt48",
"price_day": 5,
"img": "images/ico/cupis_okcupid_winline.ico",
"procent_days": 0,
"procent": 0,
"day_step": 0,
"count": {
"Claro_AR": 27
},
"totalCount": 12
}
],
"totalAmount": 1735,
"allOperators": [
"Claro_AR"
]
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | |
| **`data.services`** | array<object> | |
| **`data.services[].name`** | string | Nombre del servicio |
| **`data.services[].service`** | string | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`data.services[].price_day`** | number | Precio diario de este servicio |
| **`data.services[].img`** | string | URL del icono del servicio |
| **`data.services[].procent_days`** | integer | Días necesarios para el descuento |
| **`data.services[].procent`** | integer | Porcentaje de descuento |
| **`data.services[].day_step`** | integer | Incremento de días para el precio |
| **`data.services[].count`** | object | Números disponibles por operador para este servicio |
| **`data.services[].count.*`** | integer | |
| **`data.services[].totalCount`** | integer | Total de números disponibles para este servicio |
| **`data.totalAmount`** | integer | Total de números disponibles para todos los servicios |
| **`data.allOperators`** | array<string> | Operadores disponibles en este país |
| **`msg`** | string | Motivo del error cuando status vale 0, incluso si HTTP es 200. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Datos de alquiler (/es/docs/rental/data)
GET{"https://smspva.com/api/rent.php?method=getdata"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
**apikey** es opcional. Omítelo para datos públicos o envíalo para datos y precios personalizados según el contrato.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "getdata" | Nombre del método |
| **`apikey`** | query | string | No | (optional) | Clave API opcional; permite obtener datos personalizados. |
| **`country`** | query | string | Sí | "KZ" | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`dtype`** | query | string | No | "week" | Unidad del período: week o month. Si se omite, se usa week. |
| **`dcount`** | query | integer | No | 1 | Número de períodos; con **`dtype`**=week, número de semanas. Si se omite, se usa 1. |
| **`extend`** | query | string | No | "1" | Usa 1 para incluir **`procent_days`**, procent y **`day_step`** en cada servicio. |
## Cómo usar este método [#cómo-usar-este-método]
Consulta precios y números disponibles para tu **`country`** y duración. Usa **`week`** o **`month`** en **`dtype`** y el número de períodos en **`dcount`**.
Cada servicio incluye nombre, código, precio diario, cantidad e icono; **`data.totalAmount`** contiene el total. Añade **`extend=1`** para incluir **`procent_days`**, **`procent`** y **`day_step`**. Comprueba **`status`**: **0** indica fallo y **`msg`** explica el motivo, incluso con HTTP **200**.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
# Optional: add --data-urlencode "apikey=$SMSPVA_API_KEY" for account-specific data.
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getdata" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdata",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdata",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ.get("SMSPVA_API_KEY")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getdata",
"country": country,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getdata',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := os.Getenv("SMSPVA_API_KEY")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getdata")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getdata",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", "");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getdata");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"services": [
{
"name": "Airbnb",
"service": "opt46",
"price_day": 6,
"count": 359,
"img": "images/ico/whatsapp.png",
"procent_days": 0,
"procent": 0,
"day_step": 0
}
],
"totalAmount": 100
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | |
| **`data.services`** | array<object> | |
| **`data.services[].name`** | string | Nombre del servicio |
| **`data.services[].service`** | string | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`data.services[].price_day`** | number | Precio por día |
| **`data.services[].count`** | integer | Cantidad disponible |
| **`data.services[].img`** | string | Ruta del icono del servicio. |
| **`data.services[].procent_days`** | integer | Días necesarios para el descuento; se devuelve con **`extend=1`**. |
| **`data.services[].procent`** | integer | Porcentaje de descuento; se devuelve con **`extend=1`**. |
| **`data.services[].day_step`** | number | Incremento de días para el precio; se devuelve con **`extend=1`**. |
| **`data.totalAmount`** | integer | Total de números disponibles para todos los servicios |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Servicios predeterminados (/es/docs/rental/default-services)
GET{"https://smspva.com/api/rent.php?method=get_default_services"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Puedes llamar a este método sin clave API.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "get_default_services" | Nombre del método |
## Cómo usar este método [#cómo-usar-este-método]
Consulta la lista predeterminada de servicios de alquiler. Para ver precios y números disponibles en un país, usa [Datos de alquiler](/es/docs/rental/data) o [Datos por proveedor](/es/docs/rental/data-by-provider).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_default_services"
```
```js
const query = new URLSearchParams({
"method": "get_default_services"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const query = new URLSearchParams({
"method": "get_default_services"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
query = {
"method": "get_default_services"
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_default_services'
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
query := url.Values{}
query.Set("method", "get_default_services")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var query = new Dictionary {
["method"] = "get_default_services"
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
Map query = new LinkedHashMap<>();
query.put("method", "get_default_services");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": [
{
"name": "WhatsApp",
"service": "opt20",
"priceForDay": "0.20",
"img": "images/ico/whatsapp.png",
"DAYP": "30",
"PROC": "30"
}
]
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | array<object> | |
| **`data[].name`** | string | Nombre del servicio. |
| **`data[].service`** | string | Código del servicio. |
| **`data[].priceForDay`** | string | Precio diario del alquiler, devuelto como cadena. |
| **`data[].img`** | string | Ruta del icono del servicio. |
| **`data[].DAYP`** | string | Configuración de precios devuelta por el servidor. |
| **`data[].PROC`** | string | Configuración de precios devuelta por el servidor. |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Eliminar pedido (/es/docs/rental/delete)
GET{"https://smspva.com/api/rent.php?method=delete"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "delete" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`id`** | query | integer | Sí | "" | ID del pedido |
## Cómo usar este método [#cómo-usar-este-método]
Elimina el pedido de alquiler. Envía **GET** con **`method=delete`** y el ID que requiere este método.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=delete" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "delete",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "delete",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "delete",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'delete',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "delete")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "delete",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "delete");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"id": 123
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | |
| **`data.id`** | integer | ID del pedido |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Errores de Rental (/es/docs/rental/errors)
## HTTP 200 no garantiza éxito [#http-200-no-garantiza-éxito]
Los métodos documentan HTTP **200**, pero **status=0** es un fallo y **status=1** un éxito. Consulta **msg** si existe. No exijas **`statusCode`** ni **`error.type`** de Activation V2.
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
Este es un error que puede devolver **`restore_user`**. Su página muestra la respuesta correcta y la de error: comprueba cuál recibiste antes de leer el nuevo ID.
## Espera [#espera]
**SmsList** y **OtherSms** pueden estar vacíos con **`status=1`**. No uses la respuesta de espera 202 de Activation V2. Comprueba activación y vencimiento en [pedidos](/es/docs/rental/orders).
## Red y cuerpos vacíos [#red-y-cuerpos-vacíos]
Un timeout, cuerpo vacío o respuesta no JSON no confirma éxito. La fuente advierte que get_min_paypal_days puede devolver un cuerpo vacío si faltan country o service: incluye los parámetros obligatorios.
Si no sabes si una compra, ampliación o restauración se completó, revisa los pedidos y el historial antes de repetir: puede haber terminado aunque no recibieras la respuesta.
## Mensajes originales [#mensajes-originales]
Los ejemplos de restauración incluyen **Incorrect order id**, **Order not found**, **NOBALANCE_12.50** y **The number is busy, there is already an order for this service**. Son ejemplos de mensajes; otros métodos pueden devolver textos distintos. Consulta la [referencia del método](/es/docs/rental).
# Ejemplos de Rental (/es/docs/rental/examples)
Los [22 métodos](/es/docs/rental) incluyen cURL, JavaScript, TypeScript, Python, PHP, Go, C# y Java. Usan GET y parámetros codificados en **https://smspva.com/api/rent.php**.
## Requisitos [#requisitos]
cURL 7.76+ en shell POSIX; Node.js 22.16+ para JavaScript; proyecto Node ESM con tipos Node para TypeScript; Python 3.10+; PHP 8.1+ con curl; Go 1.20+; consola .NET 8+; Java 11+ con Jackson Databind.
Guarda JavaScript como Example.mjs, TypeScript como Example.mts, Python como Example.py y PHP como Example.php. Para C# usa Program.cs. En Java añade Jackson a tu proyecto Maven y ejecútalo con las dependencias en el classpath o mediante el IDE:
```xml
com.fasterxml.jackson.core
jackson-databind
2.22.4
```
Fuente: [Maven Central](https://central.sonatype.com/artifact/com.fasterxml.jackson.core/jackson-databind). Jackson permite comprobar status JSON incluso con HTTP 200.
## Variables [#variables]
```text
# macOS / Linux / WSL
export SMSPVA_API_KEY="YOUR_API_KEY"
```
```text
# PowerShell
$env:SMSPVA_API_KEY = "YOUR_API_KEY"
$env:SMSPVA_RENTAL_ORDER_ID = "123"
$env:SMSPVA_RENTAL_NUMBER = "79335445295"
```
Sustituye id y número por valores reales de Rental. Los métodos públicos no solicitan clave; los de clave opcional la omiten si no está configurada. Se envía como **apikey query**, no en cabeceras. Ejecuta las solicitudes de cuenta en servidor y oculta **`apikey`** en logs de acceso.
Los demás parámetros usan ejemplos de la fuente. Puedes cambiar el código o usar **`SMSPVA_RENTAL_COUNTRY`**, SERVICE, SERVICES, DTYPE, DCOUNT, SKIP, TAKE o RENT_DAYS con el prefijo completo **`SMSPVA_RENTAL_`** y solo donde se admiten. En cURL edita los literales directamente.
## Opcionales y respuestas [#opcionales-y-respuestas]
Los ejemplos mínimos omiten provider, **`partner_key`** y extend. Añádelos solo donde estén documentados. **partner_key** es query de Rental, distinto de **`partnerkey`** de Activation V2.
Los ejemplos usan timeout de 30 segundos, codifican los valores y no reintentan automáticamente. cURL imprime el cuerpo: comprueba **status** antes de usar data. Los otros lenguajes comprueban HTTP y **status=1**.
# Historial de alquiler (/es/docs/rental/history)
GET{"https://smspva.com/api/rent.php?method=get_rent_history"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "get_rent_history" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`skip`** | query | integer | No | 0 | Resultados que se omiten |
| **`take`** | query | integer | No | 10 | Cantidad de resultados |
## Cómo usar este método [#cómo-usar-este-método]
Busca alquileres terminados y comprueba **`isAvailForRestore`** para saber cuáles se pueden restaurar. Si el pedido lo permite, consulta [coste y duración](/es/docs/rental/restore-precalculation) antes de [restaurarlo](/es/docs/rental/restore).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_rent_history" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "skip=0" \
--data-urlencode "take=10"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const skip = process.env.SMSPVA_RENTAL_SKIP ?? "0";
const take = process.env.SMSPVA_RENTAL_TAKE ?? "10";
const query = new URLSearchParams({
"method": "get_rent_history",
"skip": skip,
"take": take
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const skip = process.env.SMSPVA_RENTAL_SKIP ?? "0";
const take = process.env.SMSPVA_RENTAL_TAKE ?? "10";
const query = new URLSearchParams({
"method": "get_rent_history",
"skip": skip,
"take": take
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
skip = os.environ.get("SMSPVA_RENTAL_SKIP", "0")
take = os.environ.get("SMSPVA_RENTAL_TAKE", "10")
query = {
"method": "get_rent_history",
"skip": skip,
"take": take
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_rent_history',
'skip' => $skip,
'take' => $take
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
skip := env("SMSPVA_RENTAL_SKIP", "0")
take := env("SMSPVA_RENTAL_TAKE", "10")
query := url.Values{}
query.Set("method", "get_rent_history")
query.Set("skip", skip)
query.Set("take", take)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var skip = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SKIP") ?? "0";
var take = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_TAKE") ?? "10";
var query = new Dictionary {
["method"] = "get_rent_history",
["skip"] = skip,
["take"] = take
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String skip = env("SMSPVA_RENTAL_SKIP", "0");
String take = env("SMSPVA_RENTAL_TAKE", "10");
Map query = new LinkedHashMap<>();
query.put("method", "get_rent_history");
query.put("skip", skip);
query.put("take", take);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": [
{
"orderId": 857191,
"resourceCode": "opt9",
"number": "37067787324",
"branchId": 684,
"haveSms": false,
"isAvailForRestore": true,
"days": 30,
"country": "LT",
"begin": 1768902473,
"end": 1771494473,
"closed": 1768903921
}
]
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | array<object> | |
| **`data[].orderId`** | integer | ID del pedido |
| **`data[].resourceCode`** | string | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`data[].number`** | string | Número alquilado con prefijo de país, sin el signo +. |
| **`data[].branchId`** | integer | ID interno de la rama del pedido |
| **`data[].haveSms`** | boolean | Indica si se recibieron SMS durante el alquiler. |
| **`data[].isAvailForRestore`** | boolean | Indica si se puede restaurar. Si es true, Restore renueva el alquiler con un número nuevo. |
| **`data[].days`** | integer | Días contratados en el alquiler |
| **`data[].country`** | string | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`data[].begin`** | integer | Fecha de inicio (timestamp Unix) |
| **`data[].end`** | integer | Fecha de finalización (timestamp Unix) |
| **`data[].closed`** | integer | Fecha de cierre (timestamp Unix) |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Rental API (/es/docs/rental)
Endpoint: **https://smspva.com/api/rent.php**. Todos los métodos usan **GET** y el parámetro **method**. La clave se envía en **apikey como query**, no en la cabecera de Activation V2. Comprueba **status=1**; **status=0** indica fallo incluso con HTTP 200.
Crear, activar, leer mensajes, ampliar y restaurar.
Listas de alquiler actualizadas desde la fuente existente.
## Datos de referencia [#datos-de-referencia]
| method | Descripción |
| --- | --- |
| **`getcountries`** | [Países de alquiler](/es/docs/rental/countries) |
| **`get_default_services`** | [Servicios predeterminados](/es/docs/rental/default-services) |
| **`get_country_by_service`** | [Países por servicio](/es/docs/rental/countries-by-service) |
## Precios y disponibilidad [#precios-y-disponibilidad]
| method | Descripción |
| --- | --- |
| **`getdata`** | [Datos de alquiler](/es/docs/rental/data) |
| **`getdataWithProviders`** | [Datos por proveedor](/es/docs/rental/data-by-provider) |
| **`getcount`** | [Disponibilidad de números](/es/docs/rental/count) |
| **`getCountWithProviders`** | [Disponibilidad por proveedor](/es/docs/rental/counts-by-provider) |
| **`get_count_multi`** | [Disponibilidad multiservicio](/es/docs/rental/multi-service-count) |
| **`get_days_canada_paypal`** | [Días PayPal Canadá](/es/docs/rental/canada-paypal-days) |
| **`get_min_paypal_days`** | [Días mínimos PayPal](/es/docs/rental/minimum-paypal-days) |
## Pedidos y SMS [#pedidos-y-sms]
| method | Descripción |
| --- | --- |
| **`create`** | [Crear alquiler](/es/docs/rental/create) |
| **`create_multi`** | [Crear alquiler multiservicio](/es/docs/rental/create-multi) |
| **`add_service_to_order`** | [Añadir servicio al pedido](/es/docs/rental/add-service) |
| **`orders`** | [Pedidos de alquiler](/es/docs/rental/orders) |
| **`activate`** | [Activar alquiler](/es/docs/rental/activate) |
| **`sms`** | [SMS del alquiler](/es/docs/rental/sms) |
## Gestionar alquileres [#gestionar-alquileres]
| method | Descripción |
| --- | --- |
| **`prolong`** | [Ampliar alquiler](/es/docs/rental/prolong) |
| **`prolong_max`** | [Ampliar por días](/es/docs/rental/prolong-max) |
| **`delete`** | [Eliminar pedido](/es/docs/rental/delete) |
## Historial y restauración [#historial-y-restauración]
| method | Descripción |
| --- | --- |
| **`get_rent_history`** | [Historial de alquiler](/es/docs/rental/history) |
| **`restore_user_precalc`** | [Cálculo de restauración](/es/docs/rental/restore-precalculation) |
| **`restore_user`** | [Restaurar alquiler](/es/docs/rental/restore) |
# Días mínimos PayPal (/es/docs/rental/minimum-paypal-days)
GET{"https://smspva.com/api/rent.php?method=get_min_paypal_days"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Puedes llamar a este método sin clave API.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "get_min_paypal_days" | Nombre del método |
| **`country`** | query | string | Sí | "CA" | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`service`** | query | string | Sí | "opt83" | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
## Cómo usar este método [#cómo-usar-este-método]
Consulta la duración mínima de alquiler para PayPal con **`country`** y **`service`**. Envía ambos: si falta uno, el servidor puede devolver un cuerpo HTTP vacío. Los códigos están en [Países de alquiler](/es/docs/rental/countries). Para Canadá, consulta también [Días PayPal Canadá](/es/docs/rental/canada-paypal-days).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_min_paypal_days" \
--data-urlencode "country=CA" \
--data-urlencode "service=opt83"
```
```js
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "CA";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt83";
const query = new URLSearchParams({
"method": "get_min_paypal_days",
"country": country,
"service": service
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "CA";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt83";
const query = new URLSearchParams({
"method": "get_min_paypal_days",
"country": country,
"service": service
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "CA")
service = os.environ.get("SMSPVA_RENTAL_SERVICE", "opt83")
query = {
"method": "get_min_paypal_days",
"country": country,
"service": service
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_min_paypal_days',
'country' => $country,
'service' => $service
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
country := env("SMSPVA_RENTAL_COUNTRY", "CA")
service := env("SMSPVA_RENTAL_SERVICE", "opt83")
query := url.Values{}
query.Set("method", "get_min_paypal_days")
query.Set("country", country)
query.Set("service", service)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "CA";
var service = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICE") ?? "opt83";
var query = new Dictionary {
["method"] = "get_min_paypal_days",
["country"] = country,
["service"] = service
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String country = env("SMSPVA_RENTAL_COUNTRY", "CA");
String service = env("SMSPVA_RENTAL_SERVICE", "opt83");
Map query = new LinkedHashMap<>();
query.put("method", "get_min_paypal_days");
query.put("country", country);
query.put("service", service);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"Days": 30,
"Status": 1,
"Message": ""
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | Duración mínima del alquiler y su disponibilidad. |
| **`data.Days`** | integer | Duración mínima del alquiler en días. |
| **`data.Status`** | integer | Estado de disponibilidad, distinto del status principal de la respuesta. |
| **`data.Message`** | string | Mensaje del servidor sobre la disponibilidad. |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Disponibilidad multiservicio (/es/docs/rental/multi-service-count)
GET{"https://smspva.com/api/rent.php?method=get_count_multi"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Puedes llamar a este método sin clave API.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "get_count_multi" | Nombre del método |
| **`country`** | query | string | Sí | "KZ" | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`services`** | query | string | Sí | "opt1,opt2" | Códigos de servicio separados por comas. [Lista de servicios](/es/docs/rental/reference-data) |
| **`dtype`** | query | string | No | "week" | Unidad del período: week o month |
| **`dcount`** | query | integer | No | 1 | Número de períodos; si **`dtype`**=week, es el número de semanas. |
## Cómo usar este método [#cómo-usar-este-método]
Comprueba cuántos números admiten tu combinación de servicios. Envía los códigos juntos en **`services`**. Incluye siempre **`dtype`** y **`dcount`**: los valores predeterminados de este método no son fiables.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_count_multi" \
--data-urlencode "country=KZ" \
--data-urlencode "services=opt1,opt2" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt1,opt2";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "get_count_multi",
"country": country,
"services": services,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt1,opt2";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "get_count_multi",
"country": country,
"services": services,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
services = os.environ.get("SMSPVA_RENTAL_SERVICES", "opt1,opt2")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "get_count_multi",
"country": country,
"services": services,
"dtype": dtype,
"dcount": dcount
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_count_multi',
'country' => $country,
'services' => $services,
'dtype' => $dtype,
'dcount' => $dcount
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
services := env("SMSPVA_RENTAL_SERVICES", "opt1,opt2")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "get_count_multi")
query.Set("country", country)
query.Set("services", services)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var services = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICES") ?? "opt1,opt2";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "get_count_multi",
["country"] = country,
["services"] = services,
["dtype"] = dtype,
["dcount"] = dcount
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String services = env("SMSPVA_RENTAL_SERVICES", "opt1,opt2");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "get_count_multi");
query.put("country", country);
query.put("services", services);
query.put("dtype", dtype);
query.put("dcount", dcount);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"count": 10
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | |
| **`data.count`** | integer | |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Pedidos de alquiler (/es/docs/rental/orders)
GET{"https://smspva.com/api/rent.php?method=orders"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "orders" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
## Cómo usar este método [#cómo-usar-este-método]
Consulta tus alquileres activos, su estado y las opciones de ampliación. Usa el ID para [activar](/es/docs/rental/activate), [leer SMS](/es/docs/rental/sms) o [ampliar](/es/docs/rental/prolong). Los alquileres terminados y su posibilidad de restauración están en [Historial](/es/docs/rental/history).
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=orders" \
--data-urlencode "apikey=$SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
query = {
"method": "orders"
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'orders'
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
query := url.Values{}
query.Set("method", "orders")
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var query = new Dictionary {
["method"] = "orders"
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
Map query = new LinkedHashMap<>();
query.put("method", "orders");
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": [
{
"id": 40300,
"scode": "opt16",
"sname": "Instagram",
"state": 0,
"pnumber": "9096068511",
"ccode": "+7",
"cname": "KZ",
"hasnewsms": false,
"until": 1587552240,
"canprolong": true,
"canprolongmax": 162,
"canprolonguntil": 1634883780,
"lastonline": 1586947920
}
]
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | array<object> | |
| **`data[].id`** | integer | ID del pedido |
| **`data[].scode`** | string | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`data[].sname`** | string | Nombre del servicio |
| **`data[].state`** | integer | Estado del pedido: 0 inactivo, 1 activo, 2 activándose, -1 fuera del sistema. |
| **`data[].pnumber`** | string | Número sin prefijo de país |
| **`data[].ccode`** | string | Código numérico de país |
| **`data[].cname`** | string | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`data[].hasnewsms`** | boolean | Se ha recibido un SMS nuevo para el pedido. |
| **`data[].until`** | integer | Fecha de vencimiento (timestamp Unix) |
| **`data[].canprolong`** | boolean | Indica si el pedido se puede ampliar. |
| **`data[].canprolongmax`** | integer | Máximo de días de ampliación. No se puede superar. |
| **`data[].canprolonguntil`** | integer | Fecha límite para ampliar, como timestamp Unix. Después ya no se permite. |
| **`data[].lastonline`** | integer | Última conexión del número (timestamp Unix) |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Ampliar por días (/es/docs/rental/prolong-max)
GET{"https://smspva.com/api/rent.php?method=prolong_max"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "prolong_max" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`id`** | query | integer | Sí | 123 | ID del pedido |
| **`dtype`** | query | string | Sí | "day" | Unidad de duración; debe ser siempre "day". |
| **`dcount`** | query | integer | Sí | 5 | Días de ampliación (1-6), sin superar **`canprolongmax`** del pedido. |
## Cómo usar este método [#cómo-usar-este-método]
Amplía el alquiler por días con **`dtype=day`** y **`dcount`** entre **1–6**. Consulta primero **`canprolong`**, **`canprolongmax`** y **`canprolonguntil`** en [Pedidos de alquiler](/es/docs/rental/orders). La ampliación debe respetar los límites de ese pedido.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=prolong_max" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID" \
--data-urlencode "dtype=day" \
--data-urlencode "dcount=5"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "day";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "5";
const query = new URLSearchParams({
"method": "prolong_max",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "day";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "5";
const query = new URLSearchParams({
"method": "prolong_max",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "day")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "5")
query = {
"method": "prolong_max",
"id": id,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'prolong_max',
'id' => $id,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "day")
dcount := env("SMSPVA_RENTAL_DCOUNT", "5")
query := url.Values{}
query.Set("method", "prolong_max")
query.Set("id", id)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "day";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "5";
var query = new Dictionary {
["method"] = "prolong_max",
["id"] = id,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "day");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "5");
Map query = new LinkedHashMap<>();
query.put("method", "prolong_max");
query.put("id", id);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Resultado de la ampliación por días.
**application/json**
**Ampliación de hasta 7 días completada**
```json
{
"status": 1
}
```
**Incorrect order id**
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
**Order not found**
```json
{
"status": 0,
"msg": "Order not found"
}
```
**Invalid duration parameters**
```json
{
"status": 0,
"msg": "More than 7 days or type is not day"
}
```
**Insufficient funds in account**
```json
{
"status": 0,
"msg": "Insufficient balance"
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Ampliar alquiler (/es/docs/rental/prolong)
GET{"https://smspva.com/api/rent.php?method=prolong"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "prolong" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`id`** | query | integer | Sí | 123 | ID del pedido |
| **`dtype`** | query | string | Sí | "week" | Unidad del período: week o month |
| **`dcount`** | query | integer | Sí | 1 | Número de períodos; si **`dtype`**=week, es el número de semanas. |
## Cómo usar este método [#cómo-usar-este-método]
Amplía el alquiler por el número de semanas o meses solicitado. Consulta primero **`canprolong`**, **`canprolongmax`** y **`canprolonguntil`** en [Pedidos de alquiler](/es/docs/rental/orders). La ampliación debe respetar los límites de ese pedido.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=prolong" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "prolong",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "prolong",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "prolong",
"id": id,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'prolong',
'id' => $id,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "prolong")
query.Set("id", id)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "prolong",
["id"] = id,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "prolong");
query.put("id", id);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Resultado de la ampliación del pedido.
**application/json**
**Ampliación completada**
```json
{
"status": 1
}
```
**Incorrect order id**
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
**Order not found**
```json
{
"status": 0,
"msg": "Order not found"
}
```
**Incorrect duration type**
```json
{
"status": 0,
"msg": "Incorrect duration type. Available types: week, month"
}
```
**Incorrect duration count**
```json
{
"status": 0,
"msg": "Incorrect duration count. Min 7 days. Max 90 days."
}
```
**Insufficient funds in account**
```json
{
"status": 0,
"msg": "Insufficient balance"
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Países y servicios (/es/docs/rental/reference-data)
Elige aquí los códigos de país y servicio del alquiler. Antes de crear el pedido, compara precios, proveedores, duración y disponibilidad. Los códigos y servicios pueden ser distintos de Activation V2.
Las listas se cargan al abrir la página y se actualizan cada **cinco minutos** mientras está visible. La fuente usa una caché de cinco minutos, así que los cambios pueden tardar un poco en aparecer.
[JSON actualizado](/reference-data.php) · [Datos por proveedor](/es/docs/rental/data-by-provider)
# Cálculo de restauración (/es/docs/rental/restore-precalculation)
GET{"https://smspva.com/api/rent.php?method=restore_user_precalc"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "restore_user_precalc" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`id`** | query | integer | Sí | "" | ID del pedido |
## Cómo usar este método [#cómo-usar-este-método]
Consulta el coste, la duración y la disponibilidad para restaurar un alquiler vencido. Obtén el ID en [Historial de alquiler](/es/docs/rental/history) y comprueba que **`isAvailForRestore`** sea **true**. Este cálculo es el primer paso; usa [Restaurar alquiler](/es/docs/rental/restore) para completar la restauración.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=restore_user_precalc" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user_precalc",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user_precalc",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "restore_user_precalc",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'restore_user_precalc',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "restore_user_precalc")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "restore_user_precalc",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "restore_user_precalc");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"ccode": "LT",
"scode": "opt9",
"price": 1.5,
"sname": "Instagram",
"pnumber": "37067787324",
"outdays": 5,
"orderid": 857191,
"prolongTo": 30
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | |
| **`data.ccode`** | string | Código de país del número. [Lista de países](/es/docs/rental/reference-data) |
| **`data.scode`** | string | Código de servicio [Lista de servicios](/es/docs/rental/reference-data) |
| **`data.price`** | number | Coste de restaurar el pedido |
| **`data.sname`** | string | Nombre del servicio |
| **`data.pnumber`** | string | Número alquilado con prefijo de país, sin el signo +. |
| **`data.outdays`** | integer | Días desde el vencimiento |
| **`data.orderid`** | integer | ID del pedido |
| **`data.prolongTo`** | integer | Días de vigencia del pedido restaurado |
| **`msg`** | string | Motivo del error cuando status vale 0. |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Restaurar alquiler (/es/docs/rental/restore)
GET{"https://smspva.com/api/rent.php?method=restore_user"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
Esta solicitud puede modificar un alquiler o generar cargos. Si pierdes la respuesta, comprueba los pedidos y el historial antes de repetir: el cambio puede haberse realizado. Los ejemplos no reintentan automáticamente.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "restore_user" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`id`** | query | integer | Sí | "" | ID del pedido |
## Cómo usar este método [#cómo-usar-este-método]
Restaura un alquiler terminado que cumpla los requisitos. Obtén el ID en [Historial](/es/docs/rental/history), comprueba **`isAvailForRestore`** y consulta antes [coste y duración](/es/docs/rental/restore-precalculation).
Si funciona, **`status=1`** y **`data.id`** contiene el **nuevo** ID. Úsalo en [Pedidos de alquiler](/es/docs/rental/orders). Si **`status=0`**, consulta el motivo en **`msg`**.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=restore_user" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "restore_user",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'restore_user',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "restore_user")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "restore_user",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "restore_user");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
La respuesta incluye el ID del pedido restaurado si funciona, o el motivo si falla.
**application/json**
**Restauración completada**
```json
{
"status": 1,
"data": {
"id": 123456
}
}
```
**Incorrect order ID**
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
**Order not found**
```json
{
"status": 0,
"msg": "Order not found"
}
```
**Not enough balance**
```json
{
"status": 0,
"msg": "NOBALANCE_12.50"
}
```
**Number is busy**
```json
{
"status": 0,
"msg": "The number is busy, there is already an order for this service"
}
```
**Correcto**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la solicitud. **`1`** indica que el pedido se restauró. |
| **`data`** | object | Datos del pedido restaurado. |
| **`data.id`** | integer | ID del nuevo pedido restaurado. |
Obligatorios: **`status`**, **`data`**
**Error**
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la solicitud. **`0`** indica que la restauración falló. |
| **`msg`** | string | Mensaje de error. |
Obligatorios: **`status`**, **`msg`**
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# SMS del alquiler (/es/docs/rental/sms)
GET{"https://smspva.com/api/rent.php?method=sms"}
Envía una solicitud **GET** y comprueba **`status`** en el JSON: **1** indica éxito y **0** fallo, incluso con HTTP **200**. Si falla, consulta el motivo en **`msg`**.
## Autenticación [#autenticación]
Envía **apikey** como parámetro obligatorio de **consulta**.
## Parámetros [#parámetros]
| Nombre | Ubicación | Tipo | Obligatorio | Ejemplo | Descripción |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | Sí | "sms" | Nombre del método |
| **`apikey`** | query | string | Sí | **`SMSPVA_API_KEY`** | Tu clave API La encontrarás en Profile and APIKEY, en el menú superior derecho del sitio. |
| **`id`** | query | integer | Sí | 123 | ID del pedido |
## Cómo usar este método [#cómo-usar-este-método]
Lee los mensajes del alquiler con el ID de [Pedidos de alquiler](/es/docs/rental/orders). Antes de enviar un mensaje al número, [activa el pedido](/es/docs/rental/activate) y confirma su estado en la lista.
## Ejemplos de solicitud [#ejemplos-de-solicitud]
[Entorno y dependencias](/es/docs/rental/examples). Los ejemplos codifican los parámetros y esperan hasta 30 segundos. Comprueba HTTP y **`status`** antes de usar **`data`**. cURL muestra el JSON para que lo revises; Java usa Jackson para leerlo.
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=sms" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "sms",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "sms",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "sms",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'sms',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "sms")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "sms",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "sms");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## Respuestas [#respuestas]
Consulta la respuesta correspondiente a tu solicitud. Los valores y las fechas son orientativos. Los campos opcionales pueden variar según el resultado o el formato elegido.
### HTTP 200 [#http-200]
Success
**application/json**
**Respuesta ilustrativa**
```json
{
"status": 1,
"data": {
"SmsList": [
{
"text": "Code Instagram: 671 094.",
"sender": "FACEBOOK",
"date": 1586948100
}
],
"OtherSms": []
}
}
```
| Nombre | Tipo | Descripción |
| --- | --- | --- |
| **`status`** | integer | Estado de la respuesta: 1 indica éxito; 0, fallo. |
| **`data`** | object | |
| **`data.SmsList`** | array<object> | Lista de SMS recibidos |
| **`data.SmsList[].text`** | string | Texto del SMS |
| **`data.SmsList[].sender`** | string | Remitente del SMS |
| **`data.SmsList[].date`** | integer | Fecha de recepción (timestamp Unix) |
| **`data.OtherSms`** | array<unspecified> | Lista de otros SMS |
## Guías relacionadas [#guías-relacionadas]
- [Rental API](/es/docs/rental)
- [Países y servicios](/es/docs/rental/reference-data)
- [Flujo de alquiler](/es/docs/rental/workflow)
- [Errores](/es/docs/rental/errors)
- [Esquema OpenAPI](/openapi/rental.json)
# Flujo de alquiler (/es/docs/rental/workflow)
## 1. Elegir país, servicio y duración [#1-elegir-país-servicio-y-duración]
Usa las [listas actualizadas](/es/docs/rental/reference-data) y [países](/es/docs/rental/countries). Compara precios y proveedores en [datos por proveedor](/es/docs/rental/data-by-provider) con el país y duración que vas a contratar.
Para varios servicios, envía códigos separados por comas en **services** y consulta [disponibilidad multiservicio](/es/docs/rental/multi-service-count). En ese método, pasa **dtype** y **dcount** explícitamente como recomienda la fuente. La mayoría de métodos de duración usan week/month, no días.
## 2. Crear una vez [#2-crear-una-vez]
Usa [Crear alquiler](/es/docs/rental/create) o [Crear multiservicio](/es/docs/rental/create-multi). Conserva **data.id**, **pnumber**, **ccode** y **until**. Son datos de alquiler, no de Activation V2. Ambas solicitudes usan GET y pueden crear pedidos de pago. Si se pierde la respuesta, comprueba [pedidos](/es/docs/rental/orders) antes de repetir.
## 3. Activar antes de enviar SMS [#3-activar-antes-de-enviar-sms]
Llama a [Activar](/es/docs/rental/activate) y consulta **state** en los pedidos: **0** no activo, **1** activo, **2** activando, **-1** fuera del sistema. Envía SMS solo cuando esté activo; **`status=1`** en la activación no sustituye esa comprobación.
## 4. Leer mensajes [#4-leer-mensajes]
[Rental SMS](/es/docs/rental/sms) devuelve **data.SmsList** y **data.OtherSms**. Primero comprueba **status=1**. Una lista vacía es un resultado correcto sin mensajes en esa lista; no se aplica el HTTP 202 de Activation V2.
Las lecturas repetidas pueden incluir SMS ya procesados. Guarda el estado de procesamiento en tu aplicación. Espacia el polling y deténlo al completar la tarea o vencer el alquiler; respeta las respuestas de límite de cada método. Los ejemplos hacen una solicitud sin reintentos automáticos.
## 5. Modificar o ampliar [#5-modificar-o-ampliar]
- [Añadir servicio](/es/docs/rental/add-service): requiere **`id`**, **`pnumber`** y **`service`**; **`rent_days`** es opcional.
- [Ampliar](/es/docs/rental/prolong): week/month; consulta **`canprolong`**, **`canprolongmax`** y **`canprolonguntil`**.
- [Ampliar por días](/es/docs/rental/prolong-max): **dtype=day**, **dcount=1–6**, dentro de **`canprolongmax`**.
- [Eliminar pedido](/es/docs/rental/delete): GET con **method=delete**, no HTTP DELETE.
Los ejemplos no ejecutan estas acciones automáticamente.
## 6. Restaurar [#6-restaurar]
Consulta [historial](/es/docs/rental/history) e **isAvailForRestore**. Ejecuta [cálculo previo](/es/docs/rental/restore-precalculation), revisa precio y duración y llama a [Restaurar](/es/docs/rental/restore). **data.id** contiene el nuevo pedido restaurado. HTTP 200 con **status=0** y **msg** sigue siendo un error.
## Fechas [#fechas]
La creación documenta **until** como string y la lista de pedidos como integer. Se conservan los tipos por respuesta. Los timestamps son segundos Unix; no uses el modelo **`orderExpireIn`** de Activation V2.
# SDKs y bibliotecas (/es/docs/sdks)
## Elige un SDK [#elige-un-sdk]
Los SDKs cubren los 56 métodos de Activation V2, Rental y Private Email. Elige el lenguaje y el modo de ejecución que necesite tu aplicación. Alternative API queda excluida.
Los seis SDKs tienen versiones alfa publicadas, con el código en los repositorios oficiales de SMSPVA en GitHub. Elige un paquete para instalarlo desde su registro público. Todos los SDKs usan MIT.
| Paquete | Requisitos | Estado | Versión |
| --- | --- | --- | --- |
| [SDK de Python en PyPI](https://pypi.org/project/smspva-sdk/) | Python 3.10 o posterior | Alfa publicada, síncrono y asíncrono | **`0.1.0a2`** |
| [SDK de JavaScript / TypeScript en npm](https://www.npmjs.com/package/smspva-sdk) | Node.js 22.16 o posterior | Alfa publicada, ESM y CommonJS | **`0.1.0-alpha.2`** |
| [PHP SDK](https://packagist.org/packages/smspva/sdk) | PHP 8.0+, cURL y JSON | Alfa publicada, síncrono | **`0.1.0-alpha.1`** |
| [Go SDK](https://pkg.go.dev/github.com/SMSPVA/smspva-go) | Go 1.22+ | Alfa publicada, síncrono con context | **`v0.1.0-alpha.1`** |
| [C# / .NET](https://www.nuget.org/packages/Smspva.Sdk/0.1.0-alpha.1) | .NET 8+ | Alfa publicada, asíncrono con CancellationToken | **`0.1.0-alpha.1`** |
| [Java SDK](https://central.sonatype.com/artifact/com.smspva/smspva-sdk/0.1.0-alpha.1) | Java 17+ | Alfa publicada, síncrono | **`0.1.0-alpha.1`** |
## Versiones y actualizaciones [#versiones-y-actualizaciones]
Los SDKs publicados son versiones alfa. Fija una versión para obtener instalaciones reproducibles y revisa el historial de cambios del repositorio antes de actualizar. Python usa **`0.1.0a2`**; JavaScript/TypeScript, **`0.1.0-alpha.2`**; PHP, Go, C#/.NET y Java, **`0.1.0-alpha.1`** (con el prefijo **`v`** en los comandos de Go). Son versiones preliminares, no estables.
## Python [#python]
Instala el SDK de Python desde [PyPI](https://pypi.org/project/smspva-sdk/). Usa **`--pre`** para incluir versiones alfa:
```sh
python -m pip install --pre smspva-sdk
```
Para fijar la versión actual, usa **`python -m pip install smspva-sdk==0.1.0a2`**. El código fuente, el README y el seguimiento de incidencias están en [SMSPVA/smspva-python en GitHub](https://github.com/SMSPVA/smspva-python).
Usa **`SMSPVA`** en una aplicación síncrona. Este ejemplo consulta tu saldo de Activation y obtiene los países de Rental y los proveedores de Email disponibles en ese momento:
```python
import os
from smspva import SMSPVA
with SMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
print(client.activation.get_balance())
print(client.rental.get_countries())
print(client.email.get_providers())
```
En una aplicación asíncrona, usa **`AsyncSMSPVA`** y llama a los mismos métodos con **`await`**:
```python
import asyncio
import os
from smspva import AsyncSMSPVA
async def main():
async with AsyncSMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
print(await client.activation.get_balance())
print(await client.rental.get_countries())
print(await client.email.get_providers())
asyncio.run(main())
```
El gestor de contexto cierra el grupo de conexiones al terminar. Si gestionas el cliente por tu cuenta, llama a **`close()`** o **`await aclose()`** cuando dejes de usarlo.
## JavaScript y TypeScript [#javascript-y-typescript]
Instala el SDK de JavaScript y TypeScript desde [npm](https://www.npmjs.com/package/smspva-sdk). La etiqueta **`alpha`** selecciona la última versión alfa:
```sh
npm install smspva-sdk@alpha
```
Para fijar la versión actual, usa **`npm install smspva-sdk@0.1.0-alpha.2`**. El código fuente, el README y el seguimiento de incidencias están en [SMSPVA/smspva-js en GitHub](https://github.com/SMSPVA/smspva-js).
```ts
import { SMSPVA } from 'smspva-sdk';
const client = new SMSPVA({ apiKey: process.env.SMSPVA_API_KEY });
console.log(await client.activation.getBalance());
console.log(await client.rental.getCountries());
console.log(await client.email.getProviders());
```
El mismo código funciona en JavaScript. En CommonJS, importa con **`const { SMSPVA } = require('smspva-sdk')`**. Ejecuta el SDK en tu servidor y mantén la clave API fuera del código del navegador.
## PHP [#php]
Instala el [SDK de PHP desde Packagist](https://packagist.org/packages/smspva/sdk) con Composer:
```sh
composer require "smspva/sdk:^0.1@alpha"
```
Para fijar esta versión, usa **`composer require smspva/sdk:0.1.0-alpha.1`**. El código fuente, el README y el seguimiento de incidencias están en [SMSPVA/smspva-php en GitHub](https://github.com/SMSPVA/smspva-php).
```php
activation->getBalance());
print_r($client->rental->getCountries());
print_r($client->email->getProviders());
```
Los métodos de PHP reciben arrays de parámetros descritos mediante PHPDoc generado. Devuelven arrays asociativos. El cliente es síncrono y necesita la extensión cURL.
## Go [#go]
Instala el [SDK de Go](https://pkg.go.dev/github.com/SMSPVA/smspva-go) desde su módulo etiquetado:
```sh
go get github.com/SMSPVA/smspva-go@v0.1.0-alpha.1
```
El código fuente, el README y el seguimiento de incidencias están en [SMSPVA/smspva-go en GitHub](https://github.com/SMSPVA/smspva-go). El SDK solo usa la biblioteca estándar.
El SDK de Go es un módulo de GitHub con versiones. **`pkg.go.dev`** muestra su README y la documentación generada del paquete; no es otro destino al que subir código. No necesitas una cuenta de pkg.go.dev para instalarlo. Las nuevas versiones se identifican mediante etiquetas Git en el repositorio oficial.
```go
package main
import (
"context"
"fmt"
"log"
"os"
smspva "github.com/SMSPVA/smspva-go"
)
func printResult(response smspva.Response, err error) {
if err != nil { log.Fatal(err) }
fmt.Println(string(response.Body))
}
func main() {
client, err := smspva.New(smspva.Options{APIKey: os.Getenv("SMSPVA_API_KEY")})
if err != nil { log.Fatal(err) }
defer client.CloseIdleConnections()
ctx := context.Background()
printResult(client.Activation.GetBalance(ctx))
printResult(client.Rental.GetCountries(ctx))
printResult(client.Email.GetProviders(ctx))
}
```
Guarda el programa como **`main.go`** y ejecuta **`go run .`**. Los métodos reciben **`context.Context`**, structs tipados cuando necesitan parámetros y devuelven el JSON original en **`Response.Body`**.
## C# / .NET [#c--net]
Instala el [SDK de .NET desde NuGet](https://www.nuget.org/packages/Smspva.Sdk/0.1.0-alpha.1). El código, el README y el seguimiento de incidencias están en [SMSPVA/smspva-dotnet en GitHub](https://github.com/SMSPVA/smspva-dotnet):
```sh
dotnet add package Smspva.Sdk --version 0.1.0-alpha.1
```
```csharp
using System;
using Smspva;
using var client = new SmspvaClient(Environment.GetEnvironmentVariable("SMSPVA_API_KEY"));
Console.WriteLine(await client.Activation.GetBalanceAsync());
Console.WriteLine(await client.Rental.GetCountriesAsync());
Console.WriteLine(await client.Email.GetProvidersAsync());
```
Los métodos de C# son asíncronos y aceptan **`CancellationToken`**. Las solicitudes usan records tipados y las respuestas son valores **`JsonElement`**.
## Java [#java]
Instala el [SDK de Java desde Maven Central](https://central.sonatype.com/artifact/com.smspva/smspva-sdk/0.1.0-alpha.1) añadiendo esta dependencia al **`pom.xml`** de tu aplicación:
```xml
com.smspva
smspva-sdk
0.1.0-alpha.1
```
```java
import com.smspva.sdk.SmsPva;
public class Example {
public static void main(String[] args) {
try (SmsPva client = new SmsPva(System.getenv("SMSPVA_API_KEY"))) {
System.out.println(client.activation().getBalance());
System.out.println(client.rental().getCountries());
System.out.println(client.email().getProviders());
}
}
}
```
El código, el README y el seguimiento de incidencias están en [SMSPVA/smspva-java en GitHub](https://github.com/SMSPVA/smspva-java). Java ofrece métodos síncronos, records tipados de **`Requests`** y respuestas **`JsonNode`**. Esta alfa no incluye un cliente Java asíncrono ni un ayudante de polling.
## Parámetros y respuestas [#parámetros-y-respuestas]
Obtén los códigos de país, servicio y proveedor de los listados actuales. Por ejemplo, llama a **`email.get_providers()`** en Python o **`email.getProviders()`** en JavaScript y pasa el **`pcode`** elegido a **`get_data(pcode=...)`** o **`getData({ pcode: ... })`**. Los métodos públicos de consulta funcionan sin clave API y nunca envían la clave del cliente.
Los SDK conservan los métodos HTTP, los nombres de parámetros enviados, los códigos y los tipos JSON documentados. Python y JavaScript incluyen tipos de respuesta generados. PHP devuelve arrays asociativos; Go, JSON original en **`Response.Body`**; C#, **`JsonElement`**; y Java, **`JsonNode`**. Los argumentos de solicitud están documentados o tipados para cada lenguaje.
En la consulta de disponibilidad para varios servicios de Rental, indica **`dtype`** y **`dcount`** de forma explícita. El SDK exige ambos porque la documentación de la API advierte que no se debe depender de los valores predeterminados del servidor en este método.
## Esperar un SMS y gestionar errores [#esperar-un-sms-y-gestionar-errores]
El método **`receive_sms`** / **`receiveSms`** de Activation devuelve la respuesta original de espera para HTTP **`202`** y **`SMS_NOT_YET_RECEIVED`**. Compruébala con **`is_pending`** / **`isPending`**. Al crear un pedido de Email, **`status=2`** también se devuelve como resultado de falta de disponibilidad; puedes reconocerlo con **`is_no_stock`** / **`isNoStock`**.
Para consultar un SMS repetidamente, usa **`activation.wait_for_sms`** en Python o **`activation.waitForSms`** en JavaScript. Guarda la caducidad al obtener el número y pasa ese mismo límite como **`expires_at`** (segundos Unix) o **`expiresAt`** (milisegundos Unix). El ayudante espera al menos cinco segundos entre respuestas pendientes y se detiene al llegar al límite o recibir un error. Nunca crea ni cancela pedidos. Recibir un SMS nuevo puede generar un cobro.
Cada llamada a **`receive_sms`** / **`receiveSms`** realiza una sola solicitud HTTP. Los ayudantes de espera de Python y JavaScript envían la primera solicitud inmediatamente y esperan cinco segundos después de cada respuesta pendiente antes de volver a consultar. Usa **`interval=15`** en Python o **`intervalMs: 15_000`** en JavaScript para una pausa de 15 segundos. El intervalo mínimo es una regla del ayudante, no un límite general de la API. **`await`** espera el resultado del ayudante y permite ejecutar otras tareas asíncronas durante las solicitudes y las pausas; el cliente síncrono de Python bloquea el hilo que lo llama.
Python, JavaScript y PHP notifican los fallos de la API mediante **`ApiError`**; C# y Java usan **`ApiException`**, y Go devuelve un **`APIError`**. Conservan el estado HTTP, el código de la API y la respuesta original. Los errores de protocolo y transporte se distinguen por separado. C# admite tokens de cancelación y Go admite cancelación mediante context.
Ninguna solicitud se repite automáticamente. Si se pierde la conexión durante una operación de pago o que cambia el estado, puede que no sepas si se completó. Consulta tus pedidos antes de repetirla para evitar una compra duplicada. Un método GET también puede cambiar el estado o generar un cobro.
El tiempo de espera predeterminado es de 30 segundos. Python lo aplica a cada operación de red de HTTPX; JavaScript, a la solicitud completa, incluida la lectura del cuerpo de respuesta. Puedes cambiarlo con **`timeout`** en Python o **`timeoutMs`** en JavaScript. JavaScript también acepta un **`AbortSignal`** mediante la opción **`signal`**.
PHP, Go y C# también limitan la solicitud completa de forma predeterminada. Java aplica límites por operación de red, como Python, en lugar de un plazo estricto para toda la respuesta. Java y PHP son síncronos. Consulta el README del SDK para las opciones de tiempo de espera y los tipos de error de cada lenguaje.
Puedes seguir usando los [ejemplos HTTP](/es/docs/quickstart) junto con los SDK. La página de cada método sigue siendo la referencia para sus parámetros, códigos de respuesta y advertencias importantes.
# 激活流程 (/zh/docs/activation-workflow)
## 1. 选择代码及消息类型 [#1-选择代码及消息类型]
查询[国家和服务](/zh/docs/reference-data)、[运营商](/zh/docs/api/operators)、[余量](/zh/docs/api/country-countnumbers)及[价格](/zh/docs/api/service-price)。检查[权限](/zh/docs/message-types):**`voice=0`** 短信,1 来电显示,2 语音。
价格和余量只是快照,不构成号码预留。外部供应商运营商的 9999 表示准确数量未知。
## 2. 获取号码 [#2-获取号码]
使用[获取号码](/zh/docs/api/get-number)申请号码;需要指定运营商时,使用[按运营商获取号码](/zh/docs/api/get-number-by-operator)。
保存 **`data.orderId`**,之后接收消息和管理订单都会用到。响应中的 **`data.orderExpireIn`** 是订单到期前剩余的秒数,用它计算一次到期时间:
```text
const expiresAt = Date.now() + numberResult.data.orderExpireIn * 1000;
```
之后查询消息时,一直使用这个到期时间。订单有效期以 API 返回值为准,不要固定设为十分钟,也不要在每次查询时重新计时。
如果申请请求超时,先检查[当前订单](/zh/docs/api/orders)再申请新号码:之前的请求可能已经创建订单。文档未提供用于避免重复请求的幂等键。
## 3. 等待结果 [#3-等待结果]
将 **`orderId`** 传给[接收短信](/zh/docs/api/receive-sms)。语音和来电显示也使用此接口,无需再传 **`voice`**。
| 响应 | 操作 |
| --- | --- |
| 200 | 使用 **`data.sms`**,并停止本次轮询 |
| 202 + SMS_NOT_YET_RECEIVED | 等待后在有效期内继续查询 |
| 410 + ORDER_CLOSED | 订单已关闭,停止轮询 |
| 其他错误 | 根据接口文档处理 |
等待响应也包含 **`error`**。先判断是否为 **`SMS_NOT_YET_RECEIVED`**,再处理其他错误。读取新收到的短信可能触发计费,调用时请留意。
本例采用五秒间隔,这是客户端示例设置,不是新增 API 限制。遵循返回的限流错误和订单期限。网络或非 JSON 错误会停止循环,不自动重试。
```js
// Node.js 22.16+. No automatic retries after transport errors or terminal responses.
export async function waitForSms({ apiKey, orderId, expiresAt, intervalMs = 5000 }, {
fetchImpl = fetch,
now = Date.now,
sleep = ms => new Promise(resolve => setTimeout(resolve, ms)),
baseUrl = 'https://api.smspva.com',
} = {}) {
if (!apiKey || !/^\d+$/.test(String(orderId))) throw new Error('Set your API key and order ID');
if (!Number.isFinite(expiresAt) || expiresAt <= now()) throw new Error('Order deadline has passed');
if (!Number.isFinite(intervalMs) || intervalMs < 5000) throw new Error('Use a polling interval of at least 5000 ms in this example');
while (now() < expiresAt) {
const remaining = expiresAt - now();
const response = await fetchImpl(`${baseUrl}/activation/sms/${encodeURIComponent(orderId)}`, {
headers: { apikey: apiKey },
signal: AbortSignal.timeout(Math.max(1, Math.floor(Math.min(30_000, remaining)))),
});
const result = await response.json();
if (response.status === 202 && result.statusCode === 202 && result.error?.type === 'SMS_NOT_YET_RECEIVED') {
const delay = Math.min(intervalMs, expiresAt - now());
if (delay <= 0) break;
await sleep(delay);
continue;
}
if (response.status !== 200 || result.error || result.statusCode !== 200) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
}
return result.data;
}
throw new Error('No result before the order deadline');
}
```
将函数保存为 poll-sms.mjs,并使用收到号码时计算的截止时间:
```text
import { waitForSms } from './poll-sms.mjs';
const data = await waitForSms({ apiKey, orderId, expiresAt });
console.log(data.sms);
```
[下载轮询函数](/examples/poll-sms.mjs)
## 4. 明确管理订单 [#4-明确管理订单]
- [清除短信](/zh/docs/api/clear-sms):清除当前短信以接收下一条。保留返回的 **`orderExpireIn`**。404 / NO_SMS_TO_CLEAN 不代表清除成功。
- [停止接收](/zh/docs/api/stop-sms):停止短信接收。
- [取消订单](/zh/docs/api/cancel-order):取消订单。
- [屏蔽号码](/zh/docs/api/block-number):标记号码不可用。
- [号码状态](/zh/docs/api/number-status):查询此前在同一服务用过的号码。
这些操作各有用途,不能互换。示例不会在超时后自动调用它们,请先阅读对应响应说明。
# 所有服务价格 (/zh/docs/api/all-service-prices)
GET{"https://api.smspva.com/activation/servicesprices"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`voice`** | query | integer | 否 | 类型:0 短信,1 来电显示,2 语音。默认值为 0。 (**`enum: [0,1,2]`**; **`default: 0`**) |
无需请求体。
## 使用说明 [#使用说明]
比较各国家的服务价格。也可以查询单个[服务价格](/zh/docs/api/service-price)或[国家及运营商价格](/zh/docs/api/country-operator-prices)。下单前请检查[号码余量](/zh/docs/api/countnumbers)。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/servicesprices?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/servicesprices" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/servicesprices" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/servicesprices" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/servicesprices" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/servicesprices" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/servicesprices" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": [
{
"service": "opt0",
"serviceDescription": "myopinions & erewards",
"country": "CY",
"price": "0.50"
}
]
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | array<object> | 响应数据 |
| **`data[].service`** | string | 服务 |
| **`data[].serviceDescription`** | string | 服务说明. |
| **`data[].country`** | string | 国家 |
| **`data[].price`** | string | 价格。 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 查询余额 (/zh/docs/api/balance)
GET{"https://api.smspva.com/activation/balance"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
无需路径参数、查询参数或请求体。
## 使用说明 [#使用说明]
查询账户可用余额。响应中的 **`data.balance`** 是字符串,显示金额时请保留这一类型。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/balance" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/balance";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/balance";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/balance"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/balance"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/balance";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/balance";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 400 | 缺少 **`apikey`** 请求头、值为空或长度不正确。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"balance": "10.50"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.balance`** | string | 余额 |
HTTP 400
缺少 **`apikey`** 请求头、值为空或长度不正确。
**响应示例**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 屏蔽号码 (/zh/docs/api/block-number)
PUT{"https://api.smspva.com/activation/blocknumber/{orderid}"}
**此请求可能修改订单或产生费用。** 示例不会自动重试。即使使用 GET,读取新收到的短信也可能触发计费。
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`orderid`** | path | integer | 是 | 订单 ID |
无需请求体。
## 使用说明 [#使用说明]
将此 **`orderid`** 对应的号码标记为不可用。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
- **`SMSPVA_ORDER_ID`**: **`orderid`** (必填).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_ORDER_ID:?Set SMSPVA_ORDER_ID to your orderid}"
curl --fail-with-body --max-time 30 --request PUT \
--url "https://api.smspva.com/activation/blocknumber/${SMSPVA_ORDER_ID}" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/blocknumber/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/blocknumber/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_ORDER_ID"]
url = "https://api.smspva.com/activation/blocknumber/" + quote(orderid, safe="") + ""
request = Request(url, method="PUT", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'PUT',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_ORDER_ID", "")
endpoint := "https://api.smspva.com/activation/blocknumber/" + url.PathEscape(orderid) + ""
request, err := http.NewRequest("PUT", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_ORDER_ID");
var url = "https://api.smspva.com/activation/blocknumber/" + Uri.EscapeDataString(orderid) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("PUT"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_ORDER_ID", null);
String url = "https://api.smspva.com/activation/blocknumber/" + segment(orderid) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("PUT", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 405 | 号码格式不正确 |
| 406 | 订单 ID 格式不正确或未找到。 |
| 411 | karma 过低或请求过于频繁,API 访问受限。 |
| 501 | 服务器未能处理请求。 |
| 503 | 服务器负载过高,请稍后再试。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.orderId`** | integer | 订单 ID |
HTTP 405
号码格式不正确
**响应示例**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 响应数据 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 406
订单 ID 格式不正确或未找到。
**响应示例**
```json
{
"statusCode": 406,
"error": {
"type": "ORDER_NOT_FOUND",
"description": "Order not found."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 响应数据 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 411
karma 过低或请求过于频繁,API 访问受限。
**响应示例**
```json
{
"statusCode": 411,
"error": {
"type": "ACCESS_LIMITED",
"description": "Access is temporary limited."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 501
服务器未能处理请求。
**响应示例**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_FAIL",
"description": "Server failed to process request"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 响应数据 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 503
服务器负载过高,请稍后再试。
**响应示例**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 取消订单 (/zh/docs/api/cancel-order)
PUT{"https://api.smspva.com/activation/cancelorder/{orderid}"}
**此请求可能修改订单或产生费用。** 示例不会自动重试。即使使用 GET,读取新收到的短信也可能触发计费。
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`orderid`** | path | integer | 是 | 订单 ID |
无需请求体。
## 使用说明 [#使用说明]
取消 **`orderid`** 指定的激活订单。请根据响应确认是否已取消。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
- **`SMSPVA_ORDER_ID`**: **`orderid`** (必填).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_ORDER_ID:?Set SMSPVA_ORDER_ID to your orderid}"
curl --fail-with-body --max-time 30 --request PUT \
--url "https://api.smspva.com/activation/cancelorder/${SMSPVA_ORDER_ID}" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/cancelorder/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/cancelorder/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_ORDER_ID"]
url = "https://api.smspva.com/activation/cancelorder/" + quote(orderid, safe="") + ""
request = Request(url, method="PUT", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'PUT',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_ORDER_ID", "")
endpoint := "https://api.smspva.com/activation/cancelorder/" + url.PathEscape(orderid) + ""
request, err := http.NewRequest("PUT", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_ORDER_ID");
var url = "https://api.smspva.com/activation/cancelorder/" + Uri.EscapeDataString(orderid) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("PUT"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_ORDER_ID", null);
String url = "https://api.smspva.com/activation/cancelorder/" + segment(orderid) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("PUT", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 405 | 参数不正确 |
| 406 | 订单 ID 格式不正确或未找到。 |
| 411 | karma 过低或请求过于频繁,API 访问受限。 |
| 501 | 服务器未能处理请求。 |
| 503 | 服务器负载过高,请稍后再试。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.orderId`** | integer | 订单 ID |
HTTP 405
参数不正确
**响应示例**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 406
订单 ID 格式不正确或未找到。
**响应示例**
```json
{
"statusCode": 406,
"error": {
"type": "ORDER_NOT_FOUND",
"description": "Order not found."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 411
karma 过低或请求过于频繁,API 访问受限。
**响应示例**
```json
{
"statusCode": 411,
"error": {
"type": "ACCESS_LIMITED",
"description": "Access is temporary limited."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 501
服务器未能处理请求。
**响应示例**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_BUSY",
"description": "Server failed to process request."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 503
服务器负载过高,请稍后再试。
**响应示例**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 清除短信 (/zh/docs/api/clear-sms)
PUT{"https://api.smspva.com/activation/clearsms/{orderid}"}
**此请求可能修改订单或产生费用。** 示例不会自动重试。即使使用 GET,读取新收到的短信也可能触发计费。
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`orderid`** | path | integer | 是 | 订单 ID |
无需请求体。
## 使用说明 [#使用说明]
清除当前短信,以便同一订单接收下一条。保留返回的 **`orderExpireIn`**。HTTP **404** 和 **`NO_SMS_TO_CLEAN`** 不表示已成功清除短信。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
- **`SMSPVA_ORDER_ID`**: **`orderid`** (必填).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_ORDER_ID:?Set SMSPVA_ORDER_ID to your orderid}"
curl --fail-with-body --max-time 30 --request PUT \
--url "https://api.smspva.com/activation/clearsms/${SMSPVA_ORDER_ID}" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/clearsms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/clearsms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_ORDER_ID"]
url = "https://api.smspva.com/activation/clearsms/" + quote(orderid, safe="") + ""
request = Request(url, method="PUT", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'PUT',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_ORDER_ID", "")
endpoint := "https://api.smspva.com/activation/clearsms/" + url.PathEscape(orderid) + ""
request, err := http.NewRequest("PUT", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_ORDER_ID");
var url = "https://api.smspva.com/activation/clearsms/" + Uri.EscapeDataString(orderid) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("PUT"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_ORDER_ID", null);
String url = "https://api.smspva.com/activation/clearsms/" + segment(orderid) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("PUT", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 404 | 尚未收到短信,或有待付费短信。 |
| 405 | 参数不正确 |
| 406 | 未找到订单。 |
| 501 | 服务器未能处理请求。 |
| 503 | 尚未收到短信,或有待付费短信。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456,
"orderExpireIn": 599
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.orderId`** | integer | 订单 ID |
| **`data.orderExpireIn`** | integer | 距订单到期的秒数 |
HTTP 404
尚未收到短信,或有待付费短信。
**响应示例**
```json
{
"statusCode": 404,
"error": {
"type": "NO_SMS_TO_CLEAN",
"description": "SMS not yet received or paid."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 405
参数不正确
**响应示例**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 406
未找到订单。
**响应示例**
```json
{
"statusCode": 406,
"error": {
"type": "ORDER_NOT_FOUND",
"description": "Order not found."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 501
服务器未能处理请求。
**响应示例**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_FAIL",
"description": "Server failed to process request"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 响应数据 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 503
尚未收到短信,或有待付费短信。
**响应示例**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 接收质量指标 (/zh/docs/api/conversions)
GET{"https://api.smspva.com/activation/conversions/{service}"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`service`** | path | string | 是 | 服务代码 |
无需请求体。
## 使用说明 [#使用说明]
传入 **`service`**,比较该服务在不同国家的短信接收转化率。这些数值用于衡量接收质量,不能保证某一条短信一定到达。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/conversions/opt1" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const service = process.env.SMSPVA_SERVICE ?? "opt1";
const url = "https://api.smspva.com/activation/conversions/" + encodeURIComponent(service) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const service = process.env.SMSPVA_SERVICE ?? "opt1";
const url = "https://api.smspva.com/activation/conversions/" + encodeURIComponent(service) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
service = os.environ.get("SMSPVA_SERVICE", "opt1")
url = "https://api.smspva.com/activation/conversions/" + quote(service, safe="") + ""
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
service := env("SMSPVA_SERVICE", "opt1")
endpoint := "https://api.smspva.com/activation/conversions/" + url.PathEscape(service) + ""
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt1";
var url = "https://api.smspva.com/activation/conversions/" + Uri.EscapeDataString(service) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String service = env("SMSPVA_SERVICE", "opt1");
String url = "https://api.smspva.com/activation/conversions/" + segment(service) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 400 | 未收到 API 密钥。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"service": "opt1",
"conversions": {
"UA": 3,
"KZ": 2,
"RU": 3
}
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.service`** | string | 服务代码 |
| **`data.conversions`** | object | 各国家对应的转化率 |
| **`data.conversions.*`** | integer | 质量指标,0-3,3 为最佳。 |
HTTP 400
未收到 API 密钥。
**响应示例**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 所有号码余量 (/zh/docs/api/countnumbers)
GET{"https://api.smspva.com/activation/countnumbers"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
无需路径参数、查询参数或请求体。
## 使用说明 [#使用说明]
按国家、运营商和服务查看号码余量。查询单个国家可用[国家号码余量](/zh/docs/api/country-countnumbers),比较费用可用[所有服务价格](/zh/docs/api/all-service-prices)。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/countnumbers" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/countnumbers";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/countnumbers";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/countnumbers"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/countnumbers"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/countnumbers";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/countnumbers";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 402 | 已超过 API 请求频率限制。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": [
{
"operator": "Primetel_CY",
"country": "CY",
"services": [
{
"service": "opt0",
"total": 12
}
]
}
]
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | array<object> | 响应数据 |
| **`data[].operator`** | string | 运营商 |
| **`data[].country`** | string | 国家 |
| **`data[].services`** | array<object> | |
| **`data[].services[].service`** | string | 服务 |
| **`data[].services[].total`** | integer | 号码数量 |
HTTP 402
已超过 API 请求频率限制。
**响应示例**
```json
{
"statusCode": 402,
"error": {
"type": "RATELIMIT_EXCEED",
"description": "Rate limit exceeded."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 国家号码余量 (/zh/docs/api/country-countnumbers)
GET{"https://api.smspva.com/activation/countnumbers/{country}"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | 是 | 大写两字符国家代码,采用 API 指定的 ISO 3166-2 格式。 [国家列表](/zh/docs/reference-data) |
无需请求体。
## 使用说明 [#使用说明]
传入 **`country`**,按运营商和服务查询号码余量。代码见[国家列表](/zh/docs/reference-data),下单前请比较[运营商价格](/zh/docs/api/country-operator-prices)。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/countnumbers/UK" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/countnumbers/" + encodeURIComponent(country) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/countnumbers/" + encodeURIComponent(country) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "UK")
url = "https://api.smspva.com/activation/countnumbers/" + quote(country, safe="") + ""
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "UK")
endpoint := "https://api.smspva.com/activation/countnumbers/" + url.PathEscape(country) + ""
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "UK";
var url = "https://api.smspva.com/activation/countnumbers/" + Uri.EscapeDataString(country) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "UK");
String url = "https://api.smspva.com/activation/countnumbers/" + segment(country) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": [
{
"operator": "Primetel_CY",
"country": "CY",
"services": [
{
"service": "opt0",
"total": 12
}
]
}
]
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | array<object> | 响应数据 |
| **`data[].operator`** | string | 运营商 |
| **`data[].country`** | string | 国家 |
| **`data[].services`** | array<object> | |
| **`data[].services[].service`** | string | 服务 |
| **`data[].services[].total`** | integer | 号码数量 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 国家及运营商价格 (/zh/docs/api/country-operator-prices)
GET{"https://api.smspva.com/activation/serviceprice/{country}"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | 是 | 国家代码 |
| **`voice`** | query | integer | 否 | 类型:0 短信,1 来电显示,2 语音。默认值为 0。 (**`enum: [0,1,2]`**; **`default: 0`**) |
无需请求体。
## 使用说明 [#使用说明]
比较一个 **`country`** 内各服务及运营商的价格。申请号码前,请查看[号码余量](/zh/docs/api/country-countnumbers)和[运营商代码](/zh/docs/api/operators)。
列表可能包含 SMSPVA 自营运营商和外部供应商运营商,例如 **`DonorAlpha_UK`**,两者的代码用法相同。外部号码的稳定性可能不及 SMSPVA 自营的真实 SIM 卡。外部运营商余量为 **`9999`** 时,表示无法确定准确数量,可用量可能近似不限。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/serviceprice/UK?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/serviceprice/" + encodeURIComponent(country) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/serviceprice/" + encodeURIComponent(country) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "UK")
url = "https://api.smspva.com/activation/serviceprice/" + quote(country, safe="") + "" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "UK")
endpoint := "https://api.smspva.com/activation/serviceprice/" + url.PathEscape(country) + "" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "UK";
var url = "https://api.smspva.com/activation/serviceprice/" + Uri.EscapeDataString(country) + "" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "UK");
String url = "https://api.smspva.com/activation/serviceprice/" + segment(country) + "" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 400 | 未收到 API 密钥。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": [
{
"s": "opt0",
"sd": "myopinions & erewards",
"c": "UK",
"p": "0.58",
"po": {
"Hutchison_UK": "0.58",
"ASDA_UK": "0.58",
"Vodafone_UK": "0.65"
}
}
]
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | array<object> | 响应数据 |
| **`data[].s`** | string | 服务代码 |
| **`data[].sd`** | string | 服务说明 |
| **`data[].c`** | string | 国家代码 |
| **`data[].p`** | string | 服务基础价格 |
| **`data[].po`** | object | 各运营商名称及该服务的价格 |
| **`data[].po.*`** | string | 运营商价格 |
HTTP 400
未收到 API 密钥。
**响应示例**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 消息类型设置 (/zh/docs/api/country-service-settings)
GET{"https://api.smspva.com/activation/countryservicesettings"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
无需路径参数、查询参数或请求体。
## 使用说明 [#使用说明]
检查 **`country`**、**`service`**、**`operator`** 组合允许的消息类型。传入 **`apikey`** 请求头即可,无需路径或查询参数。响应按设置 ID 升序返回全部规则,但不包含 ID 本身。
规则中每个非空条件都必须匹配;空字符串表示不限。匹配规则中,非空条件越多,优先级越高。例如,国家加服务的规则覆盖仅有国家的规则;再匹配运营商时,优先级更高。请同时使用选中规则的 **`sms`**、**`caller`**、**`voice`** 三个标记:**1** 表示允许,**0** 表示禁用。
没有匹配规则时,默认允许全部三种类型。**`data`** 为空数组表示查询成功,但没有配置规则。允许某种类型并不保证有可用号码。
查询价格和申请号码时,查询参数 **`voice`** 的含义不同:**0** 短信、**1** 来电显示、**2** 语音。比较[价格](/zh/docs/api/service-price)与下单时请选择同一类型,并单独检查[余量](/zh/docs/api/country-countnumbers)。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/countryservicesettings" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/countryservicesettings";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/countryservicesettings";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/countryservicesettings"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/countryservicesettings"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/countryservicesettings";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/countryservicesettings";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 消息类型设置;空列表同样表示查询成功。 |
| 400 | 缺少 **`apikey`** 请求头、值为空或不足 30 个字符。 |
| 401 | 未找到此 API 密钥对应的账户。 |
| 402 | 请求频率超限;此 API 使用 HTTP 402 表示该错误。 |
| 403 | 账户已被封禁。 |
| 500 | 服务器内部错误;启用错误详情时,说明可能包含具体异常。 |
HTTP 200
消息类型设置;空列表同样表示查询成功。
**服务范围规则与特定国家规则**
```json
{
"statusCode": 200,
"data": [
{
"country": "",
"service": "opt20",
"operator": "",
"voice": 0,
"caller": 0,
"sms": 1
},
{
"country": "FR",
"service": "opt20",
"operator": "",
"voice": 1,
"caller": 0,
"sms": 1
}
]
}
```
**未配置规则**
```json
{
"statusCode": 200,
"data": []
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [200]`**) |
| **`data`** | array<object> | |
| **`data[].country`** | string | 要匹配的国家代码,空字符串表示不限国家。 |
| **`data[].service`** | string | 要匹配的服务代码,空字符串表示不限服务。 |
| **`data[].operator`** | string | 要匹配的运营商代码,空字符串表示不限运营商。 |
| **`data[].voice`** | integer | 语音:1 允许,0 禁用。 (**`enum: [0,1]`**) |
| **`data[].caller`** | integer | 来电显示:1 允许,0 禁用。 (**`enum: [0,1]`**) |
| **`data[].sms`** | integer | 短信:1 允许,0 禁用。 (**`enum: [0,1]`**) |
HTTP 400
缺少 **`apikey`** 请求头、值为空或不足 30 个字符。
**响应示例**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [400]`**) |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 401
未找到此 API 密钥对应的账户。
**响应示例**
```json
{
"statusCode": 401,
"error": {
"type": "USER_NOT_FOUND",
"description": "Not found"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [401]`**) |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 402
请求频率超限;此 API 使用 HTTP 402 表示该错误。
**响应示例**
```json
{
"statusCode": 402,
"error": {
"type": "RATELIMIT_EXCEED",
"description": "Request ratelimit exeeded"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [402]`**) |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 403
账户已被封禁。
**响应示例**
```json
{
"statusCode": 403,
"error": {
"type": "USER_BANNED",
"description": "User banned"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [403]`**) |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 500
服务器内部错误;启用错误详情时,说明可能包含具体异常。
**响应示例**
```json
{
"statusCode": 500,
"error": {
"type": "SERVER_ERROR",
"description": "An internal error has occurred while processing your request."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | (**`enum: [500]`**) |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 按运营商获取号码 (/zh/docs/api/get-number-by-operator)
GET{"https://api.smspva.com/activation/number/{country}/{service}/{operator}"}
**此请求可能修改订单或产生费用。** 示例不会自动重试。即使使用 GET,读取新收到的短信也可能触发计费。
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | 是 | 大写两字符国家代码,采用 API 指定的 ISO 3166-2 格式。 [国家列表](/zh/docs/reference-data) |
| **`service`** | path | string | 是 | 服务代码。 [服务列表](/zh/docs/reference-data) |
| **`operator`** | path | string | 是 | 运营商代码,支持 SMSPVA 自营和外部运营商。 |
| **`voice`** | query | integer | 否 | 类型:0 短信,1 来电显示,2 语音。默认值为 0。 (**`enum: [0,1,2]`**; **`default: 0`**) |
无需请求体。
## 使用说明 [#使用说明]
为所选 **`country`** 和 **`service`** 指定 **`operator`** 申请号码。支持自营及外部供应商运营商代码。
代码见[基础数据](/zh/docs/reference-data)。下单前请检查[价格](/zh/docs/api/service-price)、[余量](/zh/docs/api/country-countnumbers)及[消息类型设置](/zh/docs/api/country-service-settings),也可比较[运营商价格](/zh/docs/api/country-operator-prices)和[各国价格](/zh/docs/api/service-prices)。
保存 **`data.orderId`**,用于[接收短信](/zh/docs/api/receive-sms)及管理订单。用 **`data.orderExpireIn`** 计算到期时间。请求超时后,先查[当前订单](/zh/docs/api/orders)再申请新号码:上一次请求可能已经创建订单。
有效 **`operator`** 代码见[运营商](/zh/docs/api/operators)。例如 **`DonorAlpha_UK`** 的外部运营商通过第三方提供号码,请求格式相同,但号码稳定性可能不及 SMSPVA 自营的真实 SIM 卡。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/number/BD/opt20/Grameenphone_BD?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const operator = process.env.SMSPVA_OPERATOR ?? "Grameenphone_BD";
const url = "https://api.smspva.com/activation/number/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "/" + encodeURIComponent(operator) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const operator = process.env.SMSPVA_OPERATOR ?? "Grameenphone_BD";
const url = "https://api.smspva.com/activation/number/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "/" + encodeURIComponent(operator) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "BD")
service = os.environ.get("SMSPVA_SERVICE", "opt20")
operator = os.environ.get("SMSPVA_OPERATOR", "Grameenphone_BD")
url = "https://api.smspva.com/activation/number/" + quote(country, safe="") + "/" + quote(service, safe="") + "/" + quote(operator, safe="") + "" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "BD")
service := env("SMSPVA_SERVICE", "opt20")
operator := env("SMSPVA_OPERATOR", "Grameenphone_BD")
endpoint := "https://api.smspva.com/activation/number/" + url.PathEscape(country) + "/" + url.PathEscape(service) + "/" + url.PathEscape(operator) + "" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "BD";
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt20";
var operator = Environment.GetEnvironmentVariable("SMSPVA_OPERATOR") ?? "Grameenphone_BD";
var url = "https://api.smspva.com/activation/number/" + Uri.EscapeDataString(country) + "/" + Uri.EscapeDataString(service) + "/" + Uri.EscapeDataString(operator) + "" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "BD");
String service = env("SMSPVA_SERVICE", "opt20");
String operator = env("SMSPVA_OPERATOR", "Grameenphone_BD");
String url = "https://api.smspva.com/activation/number/" + segment(country) + "/" + segment(service) + "/" + segment(operator) + "" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 405 | 参数不正确 |
| 407 | 余额不足以接收所选国家和服务的短信。 |
| 411 | karma 过低或请求过于频繁,API 访问受限。 |
| 500 | 未能获取号码。 |
| 501 | 未找到号码。 |
| 502 | 未找到号码。 |
| 503 | 服务器繁忙,请稍后再试。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456,
"phoneNumber": 9876544321,
"countryCode": "BD",
"orderExpireIn": 600
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.orderId`** | integer | 订单 ID |
| **`data.phoneNumber`** | integer | 不含国家区号的电话号码 |
| **`data.countryCode`** | string | 符合 ITU-T E.123 和 E.164 的国家代码。 [国家列表](/zh/docs/reference-data) |
| **`data.orderExpireIn`** | integer | 距订单到期的秒数 |
HTTP 405
参数不正确
**响应示例**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 407
余额不足以接收所选国家和服务的短信。
HTTP 411
karma 过低或请求过于频繁,API 访问受限。
HTTP 500
未能获取号码。
HTTP 501
未找到号码。
HTTP 502
未找到号码。
HTTP 503
服务器繁忙,请稍后再试。
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 获取号码 (/zh/docs/api/get-number)
GET{"https://api.smspva.com/activation/number/{country}/{service}"}
**此请求可能修改订单或产生费用。** 示例不会自动重试。即使使用 GET,读取新收到的短信也可能触发计费。
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | 是 | 大写两字符国家代码,采用 API 指定的 ISO 3166-2 格式。 [国家列表](/zh/docs/reference-data) |
| **`service`** | path | string | 是 | 服务代码。 [服务列表](/zh/docs/reference-data) |
| **`voice`** | query | integer | 否 | 类型:0 短信,1 来电显示,2 语音。默认值为 0。 (**`enum: [0,1,2]`**; **`default: 0`**) |
无需请求体。
## 使用说明 [#使用说明]
为所选 **`country`** 和 **`service`** 申请号码。
代码见[基础数据](/zh/docs/reference-data)。下单前请检查[价格](/zh/docs/api/service-price)、[余量](/zh/docs/api/country-countnumbers)及[消息类型设置](/zh/docs/api/country-service-settings),也可比较[运营商价格](/zh/docs/api/country-operator-prices)和[各国价格](/zh/docs/api/service-prices)。
保存 **`data.orderId`**,用于[接收短信](/zh/docs/api/receive-sms)及管理订单。用 **`data.orderExpireIn`** 计算到期时间。请求超时后,先查[当前订单](/zh/docs/api/orders)再申请新号码:上一次请求可能已经创建订单。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/number/BD/opt20?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const url = "https://api.smspva.com/activation/number/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const url = "https://api.smspva.com/activation/number/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "BD")
service = os.environ.get("SMSPVA_SERVICE", "opt20")
url = "https://api.smspva.com/activation/number/" + quote(country, safe="") + "/" + quote(service, safe="") + "" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "BD")
service := env("SMSPVA_SERVICE", "opt20")
endpoint := "https://api.smspva.com/activation/number/" + url.PathEscape(country) + "/" + url.PathEscape(service) + "" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "BD";
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt20";
var url = "https://api.smspva.com/activation/number/" + Uri.EscapeDataString(country) + "/" + Uri.EscapeDataString(service) + "" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "BD");
String service = env("SMSPVA_SERVICE", "opt20");
String url = "https://api.smspva.com/activation/number/" + segment(country) + "/" + segment(service) + "" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 405 | 参数不正确 |
| 407 | 余额不足以接收所选国家和服务的短信。 |
| 411 | karma 过低或请求过于频繁,API 访问受限。 |
| 500 | 未能获取号码。 |
| 501 | 未找到号码。 |
| 502 | 未找到号码。 |
| 503 | 服务器繁忙,请稍后再试。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456,
"phoneNumber": 9876544321,
"countryCode": "BD",
"orderExpireIn": 600
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.orderId`** | integer | 订单 ID |
| **`data.phoneNumber`** | integer | 不含国家区号的电话号码 |
| **`data.countryCode`** | string | 符合 ITU-T E.123 和 E.164 的国家代码。 [国家列表](/zh/docs/reference-data) |
| **`data.orderExpireIn`** | integer | 距订单到期的秒数 |
HTTP 405
参数不正确
**响应示例**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 407
余额不足以接收所选国家和服务的短信。
**响应示例**
```json
{
"statusCode": 407,
"error": {
"type": "LOW_BALANCE",
"description": "Low balance."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 411
karma 过低或请求过于频繁,API 访问受限。
**响应示例**
```json
{
"statusCode": 411,
"error": {
"type": "ACCESS_LIMITED",
"description": "Access is temporary limited."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 500
未能获取号码。
**响应示例**
```json
{
"statusCode": 500,
"error": {
"type": "NUMBER_FETCH_FAIL",
"description": "Failed to fetch number"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 501
未找到号码。
**响应示例**
```json
{
"statusCode": 501,
"error": {
"type": "PRICE_FETCH_FAIL",
"description": "Failed to fetch price"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | Failed to fetch price |
HTTP 502
未找到号码。
**响应示例**
```json
{
"statusCode": 502,
"error": {
"type": "NUMBER_NOT_FOUND",
"description": "Number not found."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 503
服务器繁忙,请稍后再试。
**响应示例**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# Activation V2 (/zh/docs/api)
服务器地址: **https://api.smspva.com** · **`apikey`** header.
先阅读[激活流程](/zh/docs/activation-workflow),了解如何申请号码及获取结果。下方各接口列出了参数和响应,包括表示等待的 HTTP **202**。
## 账户 [#账户]
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | **`/activation/balance`** | [查询余额](/zh/docs/api/balance) |
| GET | **`/activation/userinfo`** | [用户信息](/zh/docs/api/userinfo) |
## 基础数据 [#基础数据]
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | **`/activation/operators/{country}`** | [运营商](/zh/docs/api/operators) |
| GET | **`/activation/conversions/{service}`** | [接收质量指标](/zh/docs/api/conversions) |
| GET | **`/activation/countryservicesettings`** | [消息类型设置](/zh/docs/api/country-service-settings) |
## 余量 [#余量]
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | **`/activation/countnumbers`** | [所有号码余量](/zh/docs/api/countnumbers) |
| GET | **`/activation/countnumbers/{country}`** | [国家号码余量](/zh/docs/api/country-countnumbers) |
## 价格 [#价格]
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | **`/activation/serviceprice/{country}/{service}`** | [服务价格](/zh/docs/api/service-price) |
| GET | **`/activation/serviceprice/{country}`** | [国家及运营商价格](/zh/docs/api/country-operator-prices) |
| GET | **`/activation/serviceprices/{service}`** | [按国家查询服务价格](/zh/docs/api/service-prices) |
| GET | **`/activation/servicesprices`** | [所有服务价格](/zh/docs/api/all-service-prices) |
## 订单与结果 [#订单与结果]
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | **`/activation/number/{country}/{service}`** | [获取号码](/zh/docs/api/get-number) |
| GET | **`/activation/number/{country}/{service}/{operator}`** | [按运营商获取号码](/zh/docs/api/get-number-by-operator) |
| GET | **`/activation/sms/{orderid}`** | [接收短信](/zh/docs/api/receive-sms) |
| GET | **`/activation/orders`** | [当前订单](/zh/docs/api/orders) |
| GET | **`/activation/numberstatus/{number}/{service}`** | [号码状态](/zh/docs/api/number-status) |
## 管理订单 [#管理订单]
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| PUT | **`/activation/clearsms/{orderid}`** | [清除短信](/zh/docs/api/clear-sms) |
| PUT | **`/activation/stopsms/{orderid}`** | [停止接收短信](/zh/docs/api/stop-sms) |
| PUT | **`/activation/cancelorder/{orderid}`** | [取消订单](/zh/docs/api/cancel-order) |
| PUT | **`/activation/blocknumber/{orderid}`** | [屏蔽号码](/zh/docs/api/block-number) |
[下载 OpenAPI](/openapi/activation-v2.json)
# 号码状态 (/zh/docs/api/number-status)
GET{"https://api.smspva.com/activation/numberstatus/{number}/{service}"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`number`** | path | string | 是 | 不含国家电话区号的号码。 (**`pattern: "^[0-9]{5,}$"`**) |
| **`service`** | path | string | 是 | 服务代码,全部代码可通过 servicesprices 查询。 |
无需请求体。
## 使用说明 [#使用说明]
检查曾用号码是否仍能接收同一 **`service`** 的短信。仅适用于你已用该号码接收过该服务短信的情况。传入 **`number`** 时去掉国家电话区号。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
- **`SMSPVA_NUMBER`**: number (必填).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_NUMBER:?Set SMSPVA_NUMBER to your number}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/numberstatus/${SMSPVA_NUMBER}/opt0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const number = required("SMSPVA_NUMBER");
const service = process.env.SMSPVA_SERVICE ?? "opt0";
const url = "https://api.smspva.com/activation/numberstatus/" + encodeURIComponent(number) + "/" + encodeURIComponent(service) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const number = required("SMSPVA_NUMBER");
const service = process.env.SMSPVA_SERVICE ?? "opt0";
const url = "https://api.smspva.com/activation/numberstatus/" + encodeURIComponent(number) + "/" + encodeURIComponent(service) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
number = os.environ["SMSPVA_NUMBER"]
service = os.environ.get("SMSPVA_SERVICE", "opt0")
url = "https://api.smspva.com/activation/numberstatus/" + quote(number, safe="") + "/" + quote(service, safe="") + ""
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
number := env("SMSPVA_NUMBER", "")
service := env("SMSPVA_SERVICE", "opt0")
endpoint := "https://api.smspva.com/activation/numberstatus/" + url.PathEscape(number) + "/" + url.PathEscape(service) + ""
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var number = Required("SMSPVA_NUMBER");
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt0";
var url = "https://api.smspva.com/activation/numberstatus/" + Uri.EscapeDataString(number) + "/" + Uri.EscapeDataString(service) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String number = env("SMSPVA_NUMBER", null);
String service = env("SMSPVA_SERVICE", "opt0");
String url = "https://api.smspva.com/activation/numberstatus/" + segment(number) + "/" + segment(service) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 405 | 号码格式不正确 |
| 406 | 订单 ID 格式不正确或未找到。 |
| 500 | 服务器内部错误,说明可能包含诊断详情。 |
| 501 | 服务器未能处理请求。 |
| 502 | 未找到号码。 |
| 503 | 服务器负载过高,请稍后再试。 |
| 504 | **`av2.resp.504.desc`**:原始文档未提供此响应的完整说明。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"number": "98765432",
"orderId": 123456,
"countryCode": "+7"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.number`** | string | 不含国家电话区号的号码。 |
| **`data.orderId`** | integer | 你之前使用此号码和服务的订单 ID。 |
| **`data.countryCode`** | string | 国家电话区号。 |
HTTP 405
号码格式不正确
**响应示例**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_NUMBER_FORMAT",
"description": "Number should be integer with more than 5 digits"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 响应数据 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 406
订单 ID 格式不正确或未找到。
**响应示例**
```json
{
"statusCode": 406,
"error": {
"type": "ORDER_NOT_FOUND",
"description": "Order not found."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 500
服务器内部错误,说明可能包含诊断详情。
**响应示例**
```json
{
"statusCode": 500,
"error": {
"type": "SERVER_ERROR",
"description": "An internal error has occurred while processing your request."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 501
服务器未能处理请求。
HTTP 502
未找到号码。
HTTP 503
服务器负载过高,请稍后再试。
HTTP 504
**`av2.resp.504.desc`**:原始文档未提供此响应的完整说明。
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 运营商 (/zh/docs/api/operators)
GET{"https://api.smspva.com/activation/operators/{country}"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | 是 | 国家代码 |
无需请求体。
## 使用说明 [#使用说明]
根据 **`country`** 查询可用运营商。需要指定运营商申请号码时,使用返回的代码。
列表可能包含 SMSPVA 自营运营商和外部供应商运营商,例如 **`DonorAlpha_UK`**,两者的代码用法相同。外部号码的稳定性可能不及 SMSPVA 自营的真实 SIM 卡。外部运营商余量为 **`9999`** 时,表示无法确定准确数量,可用量可能近似不限。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/operators/UK" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/operators/" + encodeURIComponent(country) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "UK";
const url = "https://api.smspva.com/activation/operators/" + encodeURIComponent(country) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "UK")
url = "https://api.smspva.com/activation/operators/" + quote(country, safe="") + ""
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "UK")
endpoint := "https://api.smspva.com/activation/operators/" + url.PathEscape(country) + ""
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "UK";
var url = "https://api.smspva.com/activation/operators/" + Uri.EscapeDataString(country) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "UK");
String url = "https://api.smspva.com/activation/operators/" + segment(country) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 400 | 未收到 API 密钥。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"country": "UK",
"operators": [
"DonorAlpha_UK"
]
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.country`** | string | 国家代码 |
| **`data.operators`** | array<string> | 可用运营商列表 |
HTTP 400
未收到 API 密钥。
**响应示例**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 当前订单 (/zh/docs/api/orders)
GET{"https://api.smspva.com/activation/orders"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
无需路径参数、查询参数或请求体。
## 使用说明 [#使用说明]
查看当前激活订单。返回的 **`orderId`** 可用于[接收短信](/zh/docs/api/receive-sms)及其他订单管理操作。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/orders" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/orders";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/orders";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/orders"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/orders"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/orders";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/orders";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 501 | 服务器未能处理请求。 |
| 503 | 服务器负载过高,请稍后再试。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"orders": [
{
"orderId": 123456,
"phoneNumber": 987654321,
"countryCode": "+7",
"orderExpireIn": 599,
"service": "opt0",
"country": "UK",
"status": "PENDING_SMS|SMS_READY|PENDING_PAYMENT",
"sms": {
"code": "1234",
"fullText": "Your service Activation code is 1234. Don't tell it anybody"
}
}
]
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.orders`** | array<object> | 响应数据 |
| **`data.orders[].orderId`** | integer | 订单 ID |
| **`data.orders[].phoneNumber`** | integer | 不含国家区号的电话号码 |
| **`data.orders[].countryCode`** | string | 国家电话区号。 |
| **`data.orders[].orderExpireIn`** | integer | 距订单到期的秒数 |
| **`data.orders[].service`** | string | 服务代码 [服务列表](/zh/docs/reference-data) |
| **`data.orders[].country`** | string | 符合 ITU-T E.123 和 E.164 的国家代码。 [国家列表](/zh/docs/reference-data) |
| **`data.orders[].status`** | string | 短信状态。 |
| **`data.orders[].sms`** | object | 短信状态。 |
| **`data.orders[].sms.code`** | string | 短信中的服务激活码。 |
| **`data.orders[].sms.fullText`** | string | 完整短信文本。 |
HTTP 501
服务器未能处理请求。
**响应示例**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_FAIL",
"description": "Server failed to process request"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 响应数据 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 503
服务器负载过高,请稍后再试。
**响应示例**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 响应数据 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 接收短信 (/zh/docs/api/receive-sms)
GET{"https://api.smspva.com/activation/sms/{orderid}"}
**此请求可能修改订单或产生费用。** 示例不会自动重试。即使使用 GET,读取新收到的短信也可能触发计费。
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
| **`partnerkey`** | header | string | 否 | 可选推荐合作方密钥,仅在成功接收短信时使用。 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`orderid`** | path | integer | 是 | 申请号码时返回的订单 ID |
无需请求体。
## 使用说明 [#使用说明]
使用申请号码时返回的 **`orderId`**,也可从[当前订单](/zh/docs/api/orders)获取。本接口同时返回短信、来电显示和语音结果;类型已在下单时通过 **`voice=0`**、**`voice=1`** 或 **`voice=2`** 选定,这里无需再次传入 **`voice`**。
供应商的 **`text`** 原样放入 **`data.sms.code`**,**`sms`** 原样放入 **`data.sms.fullText`**。因此,**`code`** 不一定是纯数字验证码。
HTTP **202**,且 **`statusCode=202`**、**`error.type=SMS_NOT_YET_RECEIVED`** 时,表示结果仍在等待中。应先识别这一状态,再处理一般错误;稍后再查,且不要超过订单期限。三种消息类型都适用,详见[轮询指南](/zh/docs/activation-workflow)。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
- **`SMSPVA_ORDER_ID`**: **`orderid`** (必填).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_ORDER_ID:?Set SMSPVA_ORDER_ID to your orderid}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/sms/${SMSPVA_ORDER_ID}" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/sms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (response.status === 202 && result.statusCode === 202 &&
result.error?.type === "SMS_NOT_YET_RECEIVED") {
console.log("Pending. Poll again later within the order lifetime.");
} else if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/sms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (response.status === 202 && result.statusCode === 202 &&
result.error?.type === "SMS_NOT_YET_RECEIVED") {
console.log("Pending. Poll again later within the order lifetime.");
} else if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_ORDER_ID"]
url = "https://api.smspva.com/activation/sms/" + quote(orderid, safe="") + ""
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if status == 202 and result.get("statusCode") == 202 and result.get("error", {}).get("type") == "SMS_NOT_YET_RECEIVED":
print("Pending. Poll again later within the order lifetime.")
elif not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status === 202 && ($result['statusCode'] ?? 0) === 202 &&
($result['error']['type'] ?? '') === 'SMS_NOT_YET_RECEIVED') {
echo "Pending. Poll again later within the order lifetime.\n";
} elseif ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_ORDER_ID", "")
endpoint := "https://api.smspva.com/activation/sms/" + url.PathEscape(orderid) + ""
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode == 202 && result.StatusCode == 202 {
var detail struct { Type string `json:"type"` }
if json.Unmarshal(result.Error, &detail) == nil && detail.Type == "SMS_NOT_YET_RECEIVED" {
fmt.Println("Pending. Poll again later within the order lifetime.")
return
}
}
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_ORDER_ID");
var url = "https://api.smspva.com/activation/sms/" + Uri.EscapeDataString(orderid) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if ((int)response.StatusCode == 202 && apiStatus == 202 && hasError &&
error.TryGetProperty("type", out var kind) && kind.GetString() == "SMS_NOT_YET_RECEIVED")
{
Console.WriteLine("Pending. Poll again later within the order lifetime.");
}
else if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_ORDER_ID", null);
String url = "https://api.smspva.com/activation/sms/" + segment(orderid) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 202) {
// Inspect SMS_NOT_YET_RECEIVED in the raw JSON body before scheduling another poll.
System.out.println("Pending response: " + response.body());
return;
}
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 202 | 结果仍在等待中。短信、语音及来电显示均使用 **`SMS_NOT_YET_RECEIVED`** 和 **`Waiting for SMS`** 表示等待。 |
| 405 | 参数不正确 |
| 406 | 订单 ID 格式不正确或未找到。 |
| 407 | 已收到短信,但余额不足以支付。 |
| 410 | 订单已关闭,不可继续使用。 |
| 411 | karma 过低或请求过于频繁,API 访问受限。 |
| 500 | 未能获取短信。 |
| 501 | 服务器未能处理请求。 |
| 503 | 服务器负载过高,请稍后再试。 |
HTTP 200
操作成功
**SMS (voice=0)**
```json
{
"statusCode": 200,
"data": {
"sms": {
"code": "123456",
"fullText": "Your verification code is 123456"
},
"orderId": 123456,
"orderExpireIn": 420
}
}
```
**语音(voice=2)**
语音结果示例:**`fullText`** 包含文本和录音链接,格式为 **`VOICE: ...; The file: ...`**。
**`code`** 的内容取决于供应商,目前格式未确认,不保证为数字验证码。
```json
{
"statusCode": 200,
"data": {
"sms": {
"code": "",
"fullText": "VOICE: Your code is 123456; The file: https://link.smspva.com/EXAMPLE_RECORD_ID"
},
"orderId": 123456,
"orderExpireIn": 420
}
}
```
**语音:仅链接(voice=2)**
可能的格式:**`fullText`** 仅包含录音链接。此形式尚未确认,请勿依赖固定文本格式。
**`code`** 是占位示例,实际为供应商 **`text`** 字段的原始值。
```json
{
"statusCode": 200,
"data": {
"sms": {
"code": "",
"fullText": "https://link.smspva.com/EXAMPLE_RECORD_ID"
},
"orderId": 123456,
"orderExpireIn": 420
}
}
```
**来电显示(voice=1)**
JSON 结构与短信相同。字段内容为占位示例,来电显示的准确格式尚未确认。
供应商可能在 **`code`** 中返回验证码或来电号码,在 **`fullText`** 中返回消息。不要假定 **`code`** 一定为验证码。
```json
{
"statusCode": 200,
"data": {
"sms": {
"code": "",
"fullText": ""
},
"orderId": 123456,
"orderExpireIn": 420
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.sms`** | object | 收到的短信内容 |
| **`data.sms.code`** | string | 供应商 text 字段的原始内容,取决于消息类型和供应商,不一定是验证码。 |
| **`data.sms.fullText`** | string | 供应商 sms 字段的原始内容,可能是短信、语音文本和录音链接、单独录音链接或来电显示信息。 |
| **`data.orderId`** | integer | 订单 ID |
| **`data.orderExpireIn`** | integer | 距订单到期的秒数 |
HTTP 202
结果仍在等待中。短信、语音及来电显示均使用 **`SMS_NOT_YET_RECEIVED`** 和 **`Waiting for SMS`** 表示等待。
**响应示例**
```json
{
"statusCode": 202,
"error": {
"type": "SMS_NOT_YET_RECEIVED",
"description": "Waiting for SMS"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 405
参数不正确
**响应示例**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params, please re-check the specified data."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 406
订单 ID 格式不正确或未找到。
**响应示例**
```json
{
"statusCode": 406,
"error": {
"type": "INVALID_ORDER_FORMAT",
"description": "Order should be integer."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 407
已收到短信,但余额不足以支付。
**响应示例**
```json
{
"statusCode": 407,
"error": {
"type": "LOW_BALANCE",
"description": "Low balance"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 410
订单已关闭,不可继续使用。
**响应示例**
```json
{
"statusCode": 410,
"error": {
"type": "ORDER_CLOSED",
"description": "Order closed and unavailable"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 411
karma 过低或请求过于频繁,API 访问受限。
**响应示例**
```json
{
"statusCode": 411,
"error": {
"type": "ACCESS_LIMITED",
"description": "Access is temporary limited"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 500
未能获取短信。
**响应示例**
```json
{
"statusCode": 500,
"error": {
"type": "SMS_FETCH_FAIL",
"description": "Failed to fetch SMS."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 501
服务器未能处理请求。
**响应示例**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_FAIL",
"description": "Server failed to process request"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | |
| **`error.description`** | string | |
HTTP 503
服务器负载过高,请稍后再试。
**响应示例**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 服务价格 (/zh/docs/api/service-price)
GET{"https://api.smspva.com/activation/serviceprice/{country}/{service}"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`country`** | path | string | 是 | 大写两字符国家代码,采用 API 指定的 ISO 3166-2 格式。 [国家列表](/zh/docs/reference-data) |
| **`service`** | path | string | 是 | 服务代码。 [服务列表](/zh/docs/reference-data) |
| **`voice`** | query | integer | 否 | 类型:0 短信,1 来电显示,2 语音。默认值为 0。 (**`enum: [0,1,2]`**; **`default: 0`**) |
无需请求体。
## 使用说明 [#使用说明]
查询指定 **`country`** 和 **`service`** 的价格,包括 **`priceByOperators`** 中的运营商价格。代码见[基础数据](/zh/docs/reference-data),并可查看[余量](/zh/docs/api/country-countnumbers)或比较[其他国家](/zh/docs/api/service-prices)。
列表可能包含 SMSPVA 自营运营商和外部供应商运营商,例如 **`DonorAlpha_UK`**,两者的代码用法相同。外部号码的稳定性可能不及 SMSPVA 自营的真实 SIM 卡。外部运营商余量为 **`9999`** 时,表示无法确定准确数量,可用量可能近似不限。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/serviceprice/BD/opt0?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt0";
const url = "https://api.smspva.com/activation/serviceprice/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const country = process.env.SMSPVA_COUNTRY ?? "BD";
const service = process.env.SMSPVA_SERVICE ?? "opt0";
const url = "https://api.smspva.com/activation/serviceprice/" + encodeURIComponent(country) + "/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
country = os.environ.get("SMSPVA_COUNTRY", "BD")
service = os.environ.get("SMSPVA_SERVICE", "opt0")
url = "https://api.smspva.com/activation/serviceprice/" + quote(country, safe="") + "/" + quote(service, safe="") + "" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
country := env("SMSPVA_COUNTRY", "BD")
service := env("SMSPVA_SERVICE", "opt0")
endpoint := "https://api.smspva.com/activation/serviceprice/" + url.PathEscape(country) + "/" + url.PathEscape(service) + "" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_COUNTRY") ?? "BD";
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt0";
var url = "https://api.smspva.com/activation/serviceprice/" + Uri.EscapeDataString(country) + "/" + Uri.EscapeDataString(service) + "" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String country = env("SMSPVA_COUNTRY", "BD");
String service = env("SMSPVA_SERVICE", "opt0");
String url = "https://api.smspva.com/activation/serviceprice/" + segment(country) + "/" + segment(service) + "" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 405 | country 或 service 参数不正确。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"service": "opt0",
"serviceDescription": "myopinions & erewards",
"country": "KZ",
"price": "2.34",
"priceByOperators": {
"Other_KZ": "0.39",
"Activ_KZ": "0.39"
}
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.service`** | string | 服务 |
| **`data.serviceDescription`** | string | 服务说明. |
| **`data.country`** | string | 国家 |
| **`data.price`** | string | 价格。 |
| **`data.priceByOperators`** | object | 按移动运营商划分的价格。 |
| **`data.priceByOperators.*`** | string | |
HTTP 405
country 或 service 参数不正确。
**响应示例**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 按国家查询服务价格 (/zh/docs/api/service-prices)
GET{"https://api.smspva.com/activation/serviceprices/{service}"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`service`** | path | string | 是 | 服务代码。 [服务列表](/zh/docs/reference-data) (**`pattern: "^opt[0-9]{1,8}$"`**) |
| **`voice`** | query | integer | 否 | 类型:0 短信,1 来电显示,2 语音。默认值为 0。 (**`enum: [0,1,2]`**; **`default: 0`**) |
无需请求体。
## 使用说明 [#使用说明]
比较同一 **`service`** 在不同国家和运营商的价格及余量。选好后,用相应代码[按运营商获取号码](/zh/docs/api/get-number-by-operator)。
列表可能包含 SMSPVA 自营运营商和外部供应商运营商,例如 **`DonorAlpha_UK`**,两者的代码用法相同。外部号码的稳定性可能不及 SMSPVA 自营的真实 SIM 卡。外部运营商余量为 **`9999`** 时,表示无法确定准确数量,可用量可能近似不限。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/serviceprices/opt20?voice=0" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const url = "https://api.smspva.com/activation/serviceprices/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const service = process.env.SMSPVA_SERVICE ?? "opt20";
const url = "https://api.smspva.com/activation/serviceprices/" + encodeURIComponent(service) + "" + "?voice=0";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
service = os.environ.get("SMSPVA_SERVICE", "opt20")
url = "https://api.smspva.com/activation/serviceprices/" + quote(service, safe="") + "" + "?voice=0"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
service := env("SMSPVA_SERVICE", "opt20")
endpoint := "https://api.smspva.com/activation/serviceprices/" + url.PathEscape(service) + "" + "?voice=0"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var service = Environment.GetEnvironmentVariable("SMSPVA_SERVICE") ?? "opt20";
var url = "https://api.smspva.com/activation/serviceprices/" + Uri.EscapeDataString(service) + "" + "?voice=0";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String service = env("SMSPVA_SERVICE", "opt20");
String url = "https://api.smspva.com/activation/serviceprices/" + segment(service) + "" + "?voice=0";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 405 | 参数不正确 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"scode": "opt20",
"sname": "WhatsApp",
"clist": [
{
"ccode": "UK",
"cname": "United Kingdom",
"opers": [
{
"opcode": "DonorAlpha_UK",
"price": 0.65,
"count": 9999
}
]
}
]
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.scode`** | string | 服务代码。 |
| **`data.sname`** | string | 服务名称. |
| **`data.clist`** | array<object> | 该服务的可用国家和运营商。 |
| **`data.clist[].ccode`** | string | 国家代码。 |
| **`data.clist[].cname`** | string | 国家名称。 |
| **`data.clist[].opers`** | array<object> | |
| **`data.clist[].opers[].opcode`** | string | SMSPVA 自营运营商或外部供应商运营商的代码。 |
| **`data.clist[].opers[].price`** | number | 运营商价格。 (**`format: "float"`**) |
| **`data.clist[].opers[].count`** | integer | 可用号码数量。外部运营商的 **`9999`** 表示准确数量未知,可用量可能近似不限。 |
HTTP 405
参数不正确
**响应示例**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 停止接收短信 (/zh/docs/api/stop-sms)
PUT{"https://api.smspva.com/activation/stopsms/{orderid}"}
**此请求可能修改订单或产生费用。** 示例不会自动重试。即使使用 GET,读取新收到的短信也可能触发计费。
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`orderid`** | path | integer | 是 | 订单 ID |
无需请求体。
## 使用说明 [#使用说明]
停止接收此 **`orderid`** 的短信。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
- **`SMSPVA_ORDER_ID`**: **`orderid`** (必填).
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_ORDER_ID:?Set SMSPVA_ORDER_ID to your orderid}"
curl --fail-with-body --max-time 30 --request PUT \
--url "https://api.smspva.com/activation/stopsms/${SMSPVA_ORDER_ID}" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/stopsms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_ORDER_ID");
const url = "https://api.smspva.com/activation/stopsms/" + encodeURIComponent(orderid) + "";
const response = await fetch(url, {
method: "PUT",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_ORDER_ID"]
url = "https://api.smspva.com/activation/stopsms/" + quote(orderid, safe="") + ""
request = Request(url, method="PUT", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'PUT',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_ORDER_ID", "")
endpoint := "https://api.smspva.com/activation/stopsms/" + url.PathEscape(orderid) + ""
request, err := http.NewRequest("PUT", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_ORDER_ID");
var url = "https://api.smspva.com/activation/stopsms/" + Uri.EscapeDataString(orderid) + "";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("PUT"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_ORDER_ID", null);
String url = "https://api.smspva.com/activation/stopsms/" + segment(orderid) + "";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("PUT", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 405 | 参数不正确 |
| 406 | 订单 ID 格式不正确或未找到。 |
| 411 | karma 过低或请求过于频繁,API 访问受限。 |
| 501 | 服务器未能处理请求。 |
| 503 | 服务器负载过高,请稍后再试。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"orderId": 123456
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.orderId`** | integer | 订单 ID |
HTTP 405
参数不正确
**响应示例**
```json
{
"statusCode": 405,
"error": {
"type": "INVALID_PARAMS",
"description": "Invalid params."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 406
订单 ID 格式不正确或未找到。
**响应示例**
```json
{
"statusCode": 406,
"error": {
"type": "ORDER_NOT_FOUND",
"description": "Order not found."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 411
karma 过低或请求过于频繁,API 访问受限。
**响应示例**
```json
{
"statusCode": 411,
"error": {
"type": "ACCESS_LIMITED",
"description": "Access is temporary limited."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 501
服务器未能处理请求。
**响应示例**
```json
{
"statusCode": 501,
"error": {
"type": "SERVER_FAIL",
"description": "Server failed to process request."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
HTTP 503
服务器负载过高,请稍后再试。
**响应示例**
```json
{
"statusCode": 503,
"error": {
"type": "SERVER_BUSY",
"description": "Server overload, try later."
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`error`** | object | 错误详情 |
| **`error.type`** | string | 错误类型 |
| **`error.description`** | string | 错误说明 |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 用户信息 (/zh/docs/api/userinfo)
GET{"https://api.smspva.com/activation/userinfo"}
## 身份验证 [#身份验证]
| 名称 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- |
| **`apikey`** | header | string | 是 | 你的 API 密钥 |
## 参数 [#参数]
无需路径参数、查询参数或请求体。
## 使用说明 [#使用说明]
一次查询账户名称、余额和 karma。
## 请求示例 [#请求示例]
[运行环境及配置](/zh/docs/examples). cURL 使用 POSIX shell。JavaScript 示例也可用于 Node.js TypeScript 项目。Java 使用标准 HTTP 客户端并输出原始 JSON;请使用应用的 JSON 库读取响应字段。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --fail-with-body --max-time 30 --request GET \
--url "https://api.smspva.com/activation/userinfo" \
--header "apikey: $SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/userinfo";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const url = "https://api.smspva.com/activation/userinfo";
const response = await fetch(url, {
method: "GET",
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { statusCode?: number; error?: { type?: string }; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || result.error || Number(result.statusCode) >= 400) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(result)}`);
} else {
console.log(result);
}
```
```python
import json
import os
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
url = "https://api.smspva.com/activation/userinfo"
request = Request(url, method="GET", headers={"apikey": api_key})
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or result.get("error") or int(result.get("statusCode", 0)) >= 400:
raise RuntimeError(f"HTTP {status}: {result}")
else:
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'GET',
CURLOPT_HTTPHEADER => ["apikey: $apiKey"],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || !empty($result['error']) || ($result['statusCode'] ?? 0) >= 400) {
throw new RuntimeException("HTTP $status: $text");
} else {
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
```
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
endpoint := "https://api.smspva.com/activation/userinfo"
request, err := http.NewRequest("GET", endpoint, nil)
if err != nil { panic(err) }
request.Header.Set("apikey", apiKey)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
StatusCode int `json:"statusCode"`
Error json.RawMessage `json:"error"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
hasError := len(result.Error) > 0 && string(result.Error) != "null"
if response.StatusCode < 200 || response.StatusCode >= 300 || hasError || result.StatusCode >= 400 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, body))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, body, "", " "); err != nil { panic(err) }
fmt.Println(pretty.String())
}
```
```csharp
// .NET 8+ console application; no additional packages.
using System;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var url = "https://api.smspva.com/activation/userinfo";
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(new HttpMethod("GET"), url);
request.Headers.Add("apikey", apiKey);
using var response = await client.SendAsync(request);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
var apiStatus = result.TryGetProperty("statusCode", out var code) ? code.GetInt32() : 0;
var hasError = result.TryGetProperty("error", out var error) && error.ValueKind != JsonValueKind.Null;
if (!response.IsSuccessStatusCode || hasError || apiStatus >= 400)
{
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
}
else
{
Console.WriteLine(text);
}
```
```java
// Java 11+. Save as Example.java; run: java Example.java
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String segment(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String url = "https://api.smspva.com/activation/userinfo";
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(30))
.header("apikey", apiKey)
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + response.body());
}
// Java's standard library has no JSON parser. Preserve the JSON response.
// Parse statusCode/error/data with your application's JSON library before using data.
System.out.println(response.body());
}
}
```
## 响应 [#响应]
下方示例用于说明响应格式。价格、余量和账户数据仅为示例,实际数值请以 API 响应为准。
| HTTP | 说明 |
| --- | --- |
| 200 | 操作成功 |
| 400 | 缺少 **`apikey`** 请求头、值为空或长度不正确。 |
HTTP 200
操作成功
**响应示例**
```json
{
"statusCode": 200,
"data": {
"balance": "10.50",
"name": "user123",
"karma": 100.5
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | 结果状态码 |
| **`data`** | object | 响应数据 |
| **`data.balance`** | string | 余额 |
| **`data.name`** | string | 账户名称。 |
| **`data.karma`** | number | 账户 karma。 (**`format: "float"`**) |
HTTP 400
缺少 **`apikey`** 请求头、值为空或长度不正确。
**响应示例**
```json
{
"statusCode": 400,
"error": {
"type": "APIKEY_NOT_SET",
"description": "No ApiKey found"
}
}
```
**响应字段**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`statusCode`** | integer | |
| **`error`** | object | |
| **`error.type`** | string | |
| **`error.description`** | string | |
## 相关指南 [#相关指南]
- [Activation V2](/zh/docs/api)
- [基础数据](/zh/docs/reference-data)
- [激活流程](/zh/docs/activation-workflow)
- [错误与限制](/zh/docs/errors)
- [下载 OpenAPI](/openapi/activation-v2.json)
修改订单的请求发生网络故障时,先检查订单状态,再决定是否重试。
# 别名邮件 (/zh/docs/email/alias-messages)
GET{"https://smspva.com/api/rent_email.php?method=get_mails_by_alias"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "get_mails_by_alias" | 要调用的方法。 |
| **`orderid`** | query | integer | 是 | 123456 | 按所调用方法,从 Create Order、Active Orders 或 Archived Orders 获取订单 ID。 |
| **`aliasid`** | query | integer | 是 | 88 | Active Orders 的 aliases 中已有的别名 ID;**`orderid`** 必须是父订单 ID。 |
| **`t`** | query | integer | 否 | 50 | 每页返回条数。 |
| **`s`** | query | integer | 否 | 0 | 分页偏移量。 |
| **`sq`** | query | string | 否 | "verification" | 搜索文本,需要 URL 编码。 |
## 使用说明 [#使用说明]
读取已有 Gmail 别名的邮件。两个 ID 都取自[有效订单](/zh/docs/email/orders):**`orderid`** 是**父租赁订单 ID**,**`aliasid`** 是别名 ID。请先[购买访问权](/zh/docs/email/buy-alias)。
**`t`**、**`s`**、**`sq`** 与[邮件列表](/zh/docs/email/messages)用法相同。读取正文时,将父订单 **`orderid`** 和邮件 ID(作为 **`emailid`**)传给[邮件正文](/zh/docs/email/message-body)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
- **`SMSPVA_EMAIL_ALIAS_ID`**: **`aliasid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
: "${SMSPVA_EMAIL_ALIAS_ID:?Set SMSPVA_EMAIL_ALIAS_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_mails_by_alias" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID" \
--data-urlencode "aliasid=$SMSPVA_EMAIL_ALIAS_ID" \
--data-urlencode "t=${SMSPVA_EMAIL_T:-50}" \
--data-urlencode "s=${SMSPVA_EMAIL_S:-0}" \
--data-urlencode "sq=${SMSPVA_EMAIL_SQ:-verification}"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const aliasid = required("SMSPVA_EMAIL_ALIAS_ID");
const t = process.env.SMSPVA_EMAIL_T ?? "50";
const s = process.env.SMSPVA_EMAIL_S ?? "0";
const sq = process.env.SMSPVA_EMAIL_SQ ?? "verification";
const query = new URLSearchParams({
"method": "get_mails_by_alias",
"orderid": orderid,
"aliasid": aliasid,
"t": t,
"s": s,
"sq": sq
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const aliasid = required("SMSPVA_EMAIL_ALIAS_ID");
const t = process.env.SMSPVA_EMAIL_T ?? "50";
const s = process.env.SMSPVA_EMAIL_S ?? "0";
const sq = process.env.SMSPVA_EMAIL_SQ ?? "verification";
const query = new URLSearchParams({
"method": "get_mails_by_alias",
"orderid": orderid,
"aliasid": aliasid,
"t": t,
"s": s,
"sq": sq
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
aliasid = os.environ["SMSPVA_EMAIL_ALIAS_ID"]
t = os.environ.get("SMSPVA_EMAIL_T", "50")
s = os.environ.get("SMSPVA_EMAIL_S", "0")
sq = os.environ.get("SMSPVA_EMAIL_SQ", "verification")
query = {
"method": "get_mails_by_alias",
"orderid": orderid,
"aliasid": aliasid,
"t": t,
"s": s,
"sq": sq
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_mails_by_alias',
'orderid' => $orderid,
'aliasid' => $aliasid,
't' => $t,
's' => $s,
'sq' => $sq
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
aliasid := env("SMSPVA_EMAIL_ALIAS_ID", "")
t := env("SMSPVA_EMAIL_T", "50")
s := env("SMSPVA_EMAIL_S", "0")
sq := env("SMSPVA_EMAIL_SQ", "verification")
query := url.Values{}
query.Set("method", "get_mails_by_alias")
query.Set("orderid", orderid)
query.Set("aliasid", aliasid)
query.Set("t", t)
query.Set("s", s)
query.Set("sq", sq)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var aliasid = Required("SMSPVA_EMAIL_ALIAS_ID");
var t = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_T") ?? "50";
var s = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_S") ?? "0";
var sq = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_SQ") ?? "verification";
var query = new Dictionary {
["method"] = "get_mails_by_alias",
["orderid"] = orderid,
["aliasid"] = aliasid,
["t"] = t,
["s"] = s,
["sq"] = sq
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
String aliasid = env("SMSPVA_EMAIL_ALIAS_ID", null);
String t = env("SMSPVA_EMAIL_T", "50");
String s = env("SMSPVA_EMAIL_S", "0");
String sq = env("SMSPVA_EMAIL_SQ", "verification");
Map query = new LinkedHashMap<>();
query.put("method", "get_mails_by_alias");
query.put("orderid", orderid);
query.put("aliasid", aliasid);
query.put("t", t);
query.put("s", s);
query.put("sq", sq);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": [
{
"id": 6,
"sender": "noreply@example.com",
"subject": "Verification code",
"preview": "Your code: 12345",
"addedAt": "2026-10-22T10:00:00.000Z"
}
]
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Empty result**
```json
{
"status": 1,
"data": []
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].id`** | integer | 邮件 ID,作为 **`emailid`** 传给 get_mail_body。 |
| **`data[].sender`** | string | 发件人地址。 |
| **`data[].subject`** | string | 邮件主题。 |
| **`data[].preview`** | string | 邮件预览。 |
| **`data[].addedAt`** | string | 邮件时间。 (**`format: "date-time"`**) |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 归档订单 (/zh/docs/email/archived)
GET{"https://smspva.com/api/rent_email.php?method=get_archived_orders"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "get_archived_orders" | 要调用的方法。 |
## 使用说明 [#使用说明]
查询归档租赁。恢复前,用其 **`id`** 查询[当前恢复费用](/zh/docs/email/restoration-cost),再调用[恢复租赁](/zh/docs/email/restore)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_archived_orders" \
--data-urlencode "apikey=$SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "get_archived_orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "get_archived_orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
query = {
"method": "get_archived_orders"
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_archived_orders'
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
query := url.Values{}
query.Set("method", "get_archived_orders")
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var query = new Dictionary {
["method"] = "get_archived_orders"
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
Map query = new LinkedHashMap<>();
query.put("method", "get_archived_orders");
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": [
{
"id": 123455,
"address": "archived@outlook.com",
"scode": "twitter",
"pcode": "outlookcom",
"expireDate": 1767225600,
"sname": "Twitter"
}
]
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].id`** | integer | 用于恢复的归档订单 ID。 |
| **`data[].address`** | string | 邮箱地址。 |
| **`data[].scode`** | string | 服务代码。 |
| **`data[].pcode`** | string | 供应商代码。 |
| **`data[].expireDate`** | integer | 租赁到期时间,Unix 时间戳,单位为秒。 |
| **`data[].sname`** | string | 服务显示名称。 |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 购买别名访问权 (/zh/docs/email/buy-alias)
GET{"https://smspva.com/api/rent_email.php?method=buy_alias"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "buy_alias" | 要调用的方法。 |
| **`orderid`** | query | integer | 是 | 123456 | 按所调用方法,从 Create Order、Active Orders 或 Archived Orders 获取订单 ID。 |
| **`aliasid`** | query | integer | 是 | 88 | Active Orders 的 aliases 中已有的别名 ID;**`orderid`** 必须是父订单 ID。 |
## 使用说明 [#使用说明]
购买已有 Gmail 别名的访问权。在[有效订单](/zh/docs/email/orders)的 **`aliases`** 中获取 **`aliasid`**,并将父订单 ID 作为 **`orderid`**。Outlook 不支持别名。
本请求只购买订单中已有别名的访问权,不会创建新别名,也没有公开的别名生成接口。购买后可查询[别名邮件](/zh/docs/email/alias-messages)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
- **`SMSPVA_EMAIL_ALIAS_ID`**: **`aliasid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
: "${SMSPVA_EMAIL_ALIAS_ID:?Set SMSPVA_EMAIL_ALIAS_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=buy_alias" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID" \
--data-urlencode "aliasid=$SMSPVA_EMAIL_ALIAS_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const aliasid = required("SMSPVA_EMAIL_ALIAS_ID");
const query = new URLSearchParams({
"method": "buy_alias",
"orderid": orderid,
"aliasid": aliasid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const aliasid = required("SMSPVA_EMAIL_ALIAS_ID");
const query = new URLSearchParams({
"method": "buy_alias",
"orderid": orderid,
"aliasid": aliasid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
aliasid = os.environ["SMSPVA_EMAIL_ALIAS_ID"]
query = {
"method": "buy_alias",
"orderid": orderid,
"aliasid": aliasid
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'buy_alias',
'orderid' => $orderid,
'aliasid' => $aliasid
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
aliasid := env("SMSPVA_EMAIL_ALIAS_ID", "")
query := url.Values{}
query.Set("method", "buy_alias")
query.Set("orderid", orderid)
query.Set("aliasid", aliasid)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var aliasid = Required("SMSPVA_EMAIL_ALIAS_ID");
var query = new Dictionary {
["method"] = "buy_alias",
["orderid"] = orderid,
["aliasid"] = aliasid
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
String aliasid = env("SMSPVA_EMAIL_ALIAS_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "buy_alias");
query.put("orderid", orderid);
query.put("aliasid", aliasid);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": {
"alias": "sam.ple@gmail.com"
}
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | object | |
| **`data.alias`** | string | 别名地址。 |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 取消租赁 (/zh/docs/email/cancel)
GET{"https://smspva.com/api/rent_email.php?method=cancel_order"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "cancel_order" | 要调用的方法。 |
| **`orderid`** | query | integer | 是 | 123456 | 按所调用方法,从 Create Order、Active Orders 或 Archived Orders 获取订单 ID。 |
## 使用说明 [#使用说明]
取消 API 密钥所属账户的租赁。ID 取自[有效订单](/zh/docs/email/orders)。取消不保证退款。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=cancel_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "cancel_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "cancel_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
query = {
"method": "cancel_order",
"orderid": orderid
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'cancel_order',
'orderid' => $orderid
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "cancel_order")
query.Set("orderid", orderid)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var query = new Dictionary {
["method"] = "cancel_order",
["orderid"] = orderid
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "cancel_order");
query.put("orderid", orderid);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": true
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | boolean | |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 邮箱余量 (/zh/docs/email/counts)
GET{"https://smspva.com/api/rent_email.php?method=get_count"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
## 身份验证 [#身份验证]
调用此方法无需 API 密钥。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "get_count" | 要调用的方法。 |
| **`pcode`** | query | string | 否 | "outlookcom" | Get Providers 返回的供应商代码。接受全部供应商时完全省略此参数,不要传空值或 null。 |
## 使用说明 [#使用说明]
按服务查询邮箱余量。传入 **`pcode`** 查询一个供应商,省略则合计全部已启用供应商。用 **`scode`** 关联条目;缺少某服务表示余量为**零**,**`data`** 为空数组表示没有库存。
余量最多缓存 **15 秒**,查询不会预留邮箱。切换供应商时,应替换旧数据,并忽略之前选择对应的迟到响应。[创建订单](/zh/docs/email/create)时请使用同一供应商。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
设置 **`SMSPVA_EMAIL_PCODE`** 选择当前供应商;未设置或空值时完全省略 **`pcode`**。请使用实时列表中的代码。
```bash
provider_args=()
if [ -n "${SMSPVA_EMAIL_PCODE:-}" ]; then provider_args=(--data-urlencode "pcode=$SMSPVA_EMAIL_PCODE"); fi
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_count" \
"${provider_args[@]}"
```
```js
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const query = new URLSearchParams({
"method": "get_count",
"pcode": pcode
});
if (!pcode) query.delete("pcode");
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const query = new URLSearchParams({
"method": "get_count",
"pcode": pcode
});
if (!pcode) query.delete("pcode");
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
pcode = os.environ.get("SMSPVA_EMAIL_PCODE", "")
query = {
"method": "get_count",
"pcode": pcode
}
if not pcode:
del query["pcode"]
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_count',
'pcode' => $pcode
];
if ($pcode === '') unset($query['pcode']);
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
pcode := os.Getenv("SMSPVA_EMAIL_PCODE")
query := url.Values{}
query.Set("method", "get_count")
query.Set("pcode", pcode)
if pcode == "" { query.Del("pcode") }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var pcode = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_PCODE") ?? "";
var query = new Dictionary {
["method"] = "get_count",
["pcode"] = pcode
};
if (string.IsNullOrEmpty(pcode)) query.Remove("pcode");
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String pcode = env("SMSPVA_EMAIL_PCODE", "");
Map query = new LinkedHashMap<>();
query.put("method", "get_count");
query.put("pcode", pcode);
if (pcode.isEmpty()) query.remove("pcode");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": [
{
"count": 40,
"scode": "twitter"
},
{
"count": 38,
"scode": "fb"
}
]
}
```
**错误**
```json
{
"status": 0,
"msg": "Provider not found"
}
```
**Empty result**
```json
{
"status": 1,
"data": []
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].count`** | integer | 可用邮箱数量。 |
| **`data[].scode`** | string | 服务代码。 |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 创建租赁 (/zh/docs/email/create)
GET{"https://smspva.com/api/rent_email.php?method=create_order"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "create_order" | 要调用的方法。 |
| **`scode`** | query | string | 是 | "twitter" | Services and Prices 返回的服务代码。 |
| **`pcode`** | query | string | 否 | "outlookcom" | Get Providers 返回的供应商代码。接受全部供应商时完全省略此参数,不要传空值或 null。 |
| **`dtype`** | query | string | 是 | "week" | 租赁单位:day = 1 天,week = 7 天,month = 30 天。 |
| **`dcount`** | query | integer | 是 | 1 | 租赁周期数,必须为正数。 |
## 使用说明 [#使用说明]
为所选服务和时长租赁邮箱。**`scode`** 及当前价格见[服务](/zh/docs/email/services),**`pcode`** 见[供应商](/zh/docs/email/providers)。
接受任意供应商时,完全省略 **`pcode`**,不要发送 **`pcode=`**、空字符串或 null。指定供应商后,API 只会使用该供应商,即使无库存也不会自动更换。
租期为 **`dcount`** × **1**、**7** 或 **30** 天,分别对应 **`day`**、**`week`**、**`month`**。费用按日价计算,**30 天**起适用 **`months_discount`**。**`status=2`** 表示没有可用邮箱,请先刷新[余量](/zh/docs/email/counts)再尝试。
将 **`data.id`** 保存为 **`orderid`**,同时保留邮箱地址、实际供应商和到期时间。用该 ID [读取邮件](/zh/docs/email/messages)及查询[有效订单](/zh/docs/email/orders)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
设置 **`SMSPVA_EMAIL_PCODE`** 选择当前供应商;未设置或空值时完全省略 **`pcode`**。请使用实时列表中的代码。
- **`SMSPVA_EMAIL_SCODE`**: **`scode`**.
```bash
provider_args=()
if [ -n "${SMSPVA_EMAIL_PCODE:-}" ]; then provider_args=(--data-urlencode "pcode=$SMSPVA_EMAIL_PCODE"); fi
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_SCODE:?Set SMSPVA_EMAIL_SCODE}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=create_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
"${provider_args[@]}" \
--data-urlencode "scode=$SMSPVA_EMAIL_SCODE" \
--data-urlencode "dtype=${SMSPVA_EMAIL_DTYPE:-week}" \
--data-urlencode "dcount=${SMSPVA_EMAIL_DCOUNT:-1}"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const scode = required("SMSPVA_EMAIL_SCODE");
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const dtype = process.env.SMSPVA_EMAIL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_EMAIL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "create_order",
"scode": scode,
"pcode": pcode,
"dtype": dtype,
"dcount": dcount
});
if (!pcode) query.delete("pcode");
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const scode = required("SMSPVA_EMAIL_SCODE");
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const dtype = process.env.SMSPVA_EMAIL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_EMAIL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "create_order",
"scode": scode,
"pcode": pcode,
"dtype": dtype,
"dcount": dcount
});
if (!pcode) query.delete("pcode");
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
scode = os.environ["SMSPVA_EMAIL_SCODE"]
pcode = os.environ.get("SMSPVA_EMAIL_PCODE", "")
dtype = os.environ.get("SMSPVA_EMAIL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_EMAIL_DCOUNT", "1")
query = {
"method": "create_order",
"scode": scode,
"pcode": pcode,
"dtype": dtype,
"dcount": dcount
}
if not pcode:
del query["pcode"]
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'create_order',
'scode' => $scode,
'pcode' => $pcode,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($pcode === '') unset($query['pcode']);
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
scode := env("SMSPVA_EMAIL_SCODE", "")
pcode := os.Getenv("SMSPVA_EMAIL_PCODE")
dtype := env("SMSPVA_EMAIL_DTYPE", "week")
dcount := env("SMSPVA_EMAIL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "create_order")
query.Set("scode", scode)
query.Set("pcode", pcode)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if pcode == "" { query.Del("pcode") }
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var scode = Required("SMSPVA_EMAIL_SCODE");
var pcode = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_PCODE") ?? "";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "create_order",
["scode"] = scode,
["pcode"] = pcode,
["dtype"] = dtype,
["dcount"] = dcount
};
if (string.IsNullOrEmpty(pcode)) query.Remove("pcode");
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String scode = env("SMSPVA_EMAIL_SCODE", null);
String pcode = env("SMSPVA_EMAIL_PCODE", "");
String dtype = env("SMSPVA_EMAIL_DTYPE", "week");
String dcount = env("SMSPVA_EMAIL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "create_order");
query.put("scode", scode);
query.put("pcode", pcode);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (pcode.isEmpty()) query.remove("pcode");
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**供应商不存在或已停用**
```json
{
"status": 0,
"errorid": 9,
"errormsg": "Provider not found",
"msg": "Provider not found"
}
```
**成功响应示例**
```json
{
"status": 1,
"data": {
"id": 123456,
"email": "mailbox@outlook.com",
"scode": "twitter",
"pcode": "outlookcom",
"expireDate": 1855324800
}
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**暂无可用邮箱**
```json
{
"status": 2
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | object | |
| **`data.id`** | integer | 订单 ID,后续请求中作为 **`orderid`** 传入。 |
| **`data.email`** | string | 分配的邮箱地址。 |
| **`data.scode`** | string | 服务代码。 |
| **`data.pcode`** | string | 实际分配的供应商代码。 |
| **`data.expireDate`** | integer | 租赁到期时间,Unix 时间戳,单位为秒。 |
必填: **`status`**, **`data`**
**暂无可用邮箱**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [2]`**) |
必填: **`status`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 错误与响应代码 (/zh/docs/email/errors)
## 检查请求结果 [#检查请求结果]
HTTP **200** 本身不代表成功。请检查 **`status`**:**1** 成功,**0** 错误,创建时 **2** 表示暂无邮箱。解析 JSON 的示例会同时检查 HTTP 和 **`status`**,cURL 则输出 JSON 供你检查。
错误原因可能在 **`msg`**、**`errormsg`** 或 **`errorid`** 中。有些错误只有 **`msg`**;只要 **`status=0`** 就表示失败,不必等待数字错误码。
## 错误代码 [#错误代码]
| **`errorid`** | 含义 |
| --- | --- |
| **2** | 服务不存在或不可用 |
| **7** | 请求参数不正确 |
| **9** | 供应商不存在或已停用 |
| **10** | 有效订单数量已达上限 |
| **16** | 创建订单请求过于频繁 |
遇到 **`errorid=9`** 时,刷新[供应商](/zh/docs/email/providers)。创建时若 **`status=2`**,请刷新[邮箱余量](/zh/docs/email/counts)。
## 可能收到的错误信息 [#可能收到的错误信息]
**`Incorrect apikey`** 表示密钥缺失或格式错误,**`Unknown apikey`** 表示找不到账户。**`User is not owner of order`** 表示需要订单所属账户的密钥。余额错误包括 **`Balance is not enough`** 和 **`Balance is lower than zero`**(余额非正数)。
其他可能的信息如下。报告问题时,请保留原始信息、**`status`** 及其他错误字段。
- **`Order not found`**
- **`Aliases are only available for Gmail`**
- **`Incorrect service code`**
- **`Incorrect duration type`**
- **`Incorrect duration count`**
- **`Incorrect order id`**
- **`Incorrect email id`**
- **`Email service temporarily unavailable`**
- **`Incorrect method`**
# 示例与环境 (/zh/docs/email/examples)
每个接口提供相同八种语言示例。使用实时服务代码及自己的订单、邮件和别名 ID,按需设置环境变量。以下列出运行环境、命令及依赖。
## 运行环境 [#运行环境]
| 语言 | 环境 |
| --- | --- |
| cURL | Bash、cURL 7.76+;检查输出 JSON 的 status |
| JavaScript / TypeScript | Node.js 22+; TypeScript 5+ 及 Node 类型 |
| Python | Python 3.10+, 标准库 |
| PHP | PHP 8.1+ 及 ext-curl |
| Go | Go 1.22+, 标准库 |
| C# | .NET 8+, 控制台应用 |
| Java | Java 11+, classpath 中包含 Jackson Databind |
Java 使用 Jackson 检查 JSON status。Maven 依赖 ([Maven Central](https://central.sonatype.com/artifact/com.fasterxml.jackson.core/jackson-databind)):
```xml
com.fasterxml.jackson.core
jackson-databind
2.22.4
```
```bash
# Bash / macOS / Linux
export SMSPVA_API_KEY='YOUR_API_KEY'
export SMSPVA_EMAIL_SCODE='CODE_FROM_LIVE_SERVICES'
export SMSPVA_EMAIL_ORDER_ID='YOUR_EMAIL_ORDER_ID'
export SMSPVA_EMAIL_MESSAGE_ID='ID_FROM_GET_MAILS'
export SMSPVA_EMAIL_ALIAS_ID='ID_FROM_ORDER_ALIASES'
# Optional: set SMSPVA_EMAIL_PCODE from get_providers; unset means any provider.
unset SMSPVA_EMAIL_PCODE
```
```powershell
$env:SMSPVA_API_KEY = 'YOUR_API_KEY'
$env:SMSPVA_EMAIL_SCODE = 'CODE_FROM_LIVE_SERVICES'
$env:SMSPVA_EMAIL_ORDER_ID = 'YOUR_EMAIL_ORDER_ID'
$env:SMSPVA_EMAIL_MESSAGE_ID = 'ID_FROM_GET_MAILS'
$env:SMSPVA_EMAIL_ALIAS_ID = 'ID_FROM_ORDER_ALIASES'
Remove-Item Env:SMSPVA_EMAIL_PCODE -ErrorAction SilentlyContinue
```
| 变量 | 参数 |
| --- | --- |
| **`SMSPVA_EMAIL_DTYPE`** | **`dtype`**,默认为 week |
| **`SMSPVA_EMAIL_DCOUNT`** | **`dcount`**,默认为 1 |
| **`SMSPVA_EMAIL_T`** | **`t`**, page size, default 50 |
| **`SMSPVA_EMAIL_S`** | **`s`**, offset, default 0 |
| **`SMSPVA_EMAIL_SQ`** | **`sq`**, search, example verification |
| **`SMSPVA_EMAIL_PCODE`** | **`pcode`**,空值时省略 |
cURL 示例在 Bash 中运行。Java 保存为 **`Example.java`**,Go 保存为 **`main.go`**,C# 放在 .NET 控制台项目的 **`Program.cs`** 中。TypeScript 先编译再运行,其他示例直接读取环境变量。
请求会编码查询参数,并设置 30 秒超时。账户密钥位于 URL 中,请从公开请求日志中隐去。公开基础数据接口不会发送密钥,即使环境中已设置密钥也一样。
使用自己账户的邮箱相关 ID。示例不会自动重试付费请求;结果不明时,先检查订单再决定是否重复。
# Private Email Rental API (/zh/docs/email)
地址:**https://smspva.com/api/rent_email.php**。全部 14 个接口通过 **GET** 与 **method** 选择。受保护方法使用订单所属账户的 **apikey 查询参数**。HTTP 200 时也需检查 **status**:**1** 成功,**0** 错误,创建时 **2** 表示暂无邮箱。错误详情可能包含 **msg**、**errormsg**、**errorid**。
## 基础数据 [#基础数据]
| method | 说明 |
| --- | --- |
| **`get_providers`** | [供应商](/zh/docs/email/providers) |
| **`get_data`** | [服务与价格](/zh/docs/email/services) |
| **`get_count`** | [邮箱余量](/zh/docs/email/counts) |
## 邮箱与邮件 [#邮箱与邮件]
| method | 说明 |
| --- | --- |
| **`create_order`** | [创建租赁](/zh/docs/email/create) |
| **`get_orders`** | [有效订单](/zh/docs/email/orders) |
| **`get_mails`** | [邮件列表](/zh/docs/email/messages) |
| **`get_mail_body`** | [邮件正文](/zh/docs/email/message-body) |
## 管理租赁与别名 [#管理租赁与别名]
| method | 说明 |
| --- | --- |
| **`buy_alias`** | [购买别名访问权](/zh/docs/email/buy-alias) |
| **`get_mails_by_alias`** | [别名邮件](/zh/docs/email/alias-messages) |
| **`prolong_order`** | [延长租赁](/zh/docs/email/prolong) |
| **`cancel_order`** | [取消租赁](/zh/docs/email/cancel) |
## 归档与恢复 [#归档与恢复]
| method | 说明 |
| --- | --- |
| **`get_archived_orders`** | [归档订单](/zh/docs/email/archived) |
| **`calc_restore_order`** | [恢复费用](/zh/docs/email/restoration-cost) |
| **`restore_order`** | [恢复租赁](/zh/docs/email/restore) |
# 邮件正文 (/zh/docs/email/message-body)
GET{"https://smspva.com/api/rent_email.php?method=get_mail_body"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "get_mail_body" | 要调用的方法。 |
| **`orderid`** | query | integer | 是 | 123456 | 按所调用方法,从 Create Order、Active Orders 或 Archived Orders 获取订单 ID。 |
| **`emailid`** | query | integer | 是 | 6 | 邮件列表接口返回的邮件 ID。 |
## 使用说明 [#使用说明]
用[邮件列表](/zh/docs/email/messages)或[别名邮件](/zh/docs/email/alias-messages)中的 **`emailid`** 读取完整内容,同时传入父租赁订单的 **`orderid`**。
**`body`** 可能包含发件人的 HTML。请将其视为不可信内容,在应用中显示前进行清理。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
- **`SMSPVA_EMAIL_MESSAGE_ID`**: **`emailid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
: "${SMSPVA_EMAIL_MESSAGE_ID:?Set SMSPVA_EMAIL_MESSAGE_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_mail_body" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID" \
--data-urlencode "emailid=$SMSPVA_EMAIL_MESSAGE_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const emailid = required("SMSPVA_EMAIL_MESSAGE_ID");
const query = new URLSearchParams({
"method": "get_mail_body",
"orderid": orderid,
"emailid": emailid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const emailid = required("SMSPVA_EMAIL_MESSAGE_ID");
const query = new URLSearchParams({
"method": "get_mail_body",
"orderid": orderid,
"emailid": emailid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
emailid = os.environ["SMSPVA_EMAIL_MESSAGE_ID"]
query = {
"method": "get_mail_body",
"orderid": orderid,
"emailid": emailid
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_mail_body',
'orderid' => $orderid,
'emailid' => $emailid
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
emailid := env("SMSPVA_EMAIL_MESSAGE_ID", "")
query := url.Values{}
query.Set("method", "get_mail_body")
query.Set("orderid", orderid)
query.Set("emailid", emailid)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var emailid = Required("SMSPVA_EMAIL_MESSAGE_ID");
var query = new Dictionary {
["method"] = "get_mail_body",
["orderid"] = orderid,
["emailid"] = emailid
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
String emailid = env("SMSPVA_EMAIL_MESSAGE_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "get_mail_body");
query.put("orderid", orderid);
query.put("emailid", emailid);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": {
"id": 6,
"sender": "noreply@example.com",
"subject": "Verification code",
"body": "Your code: 12345
",
"addedAt": "2026-10-22T10:00:00.000Z"
}
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | object | |
| **`data.id`** | integer | 邮件 ID。 |
| **`data.sender`** | string | 发件人地址。 |
| **`data.subject`** | string | 邮件主题。 |
| **`data.body`** | string | 邮件正文,可能包含 HTML。显示前请按不可信内容处理。 |
| **`data.addedAt`** | string | 邮件时间。 (**`format: "date-time"`**) |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 邮件列表 (/zh/docs/email/messages)
GET{"https://smspva.com/api/rent_email.php?method=get_mails"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "get_mails" | 要调用的方法。 |
| **`orderid`** | query | integer | 是 | 123456 | 按所调用方法,从 Create Order、Active Orders 或 Archived Orders 获取订单 ID。 |
| **`t`** | query | integer | 否 | 50 | 每页返回条数。 |
| **`s`** | query | integer | 否 | 0 | 分页偏移量。 |
| **`sq`** | query | string | 否 | "verification" | 搜索文本,需要 URL 编码。 |
## 使用说明 [#使用说明]
查看你拥有的租赁邮箱中的邮件预览。**`orderid`** 取自[有效订单](/zh/docs/email/orders)。**`t`** 为每页条数,**`s`** 为偏移;可选搜索参数 **`sq`** 需 URL 编码。
读取完整内容时,将邮件 **`id`** 作为 **`emailid`** 传给[邮件正文](/zh/docs/email/message-body)。**`data`** 为空数组表示查询成功,但没有匹配邮件。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_mails" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID" \
--data-urlencode "t=${SMSPVA_EMAIL_T:-50}" \
--data-urlencode "s=${SMSPVA_EMAIL_S:-0}" \
--data-urlencode "sq=${SMSPVA_EMAIL_SQ:-verification}"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const t = process.env.SMSPVA_EMAIL_T ?? "50";
const s = process.env.SMSPVA_EMAIL_S ?? "0";
const sq = process.env.SMSPVA_EMAIL_SQ ?? "verification";
const query = new URLSearchParams({
"method": "get_mails",
"orderid": orderid,
"t": t,
"s": s,
"sq": sq
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const t = process.env.SMSPVA_EMAIL_T ?? "50";
const s = process.env.SMSPVA_EMAIL_S ?? "0";
const sq = process.env.SMSPVA_EMAIL_SQ ?? "verification";
const query = new URLSearchParams({
"method": "get_mails",
"orderid": orderid,
"t": t,
"s": s,
"sq": sq
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
t = os.environ.get("SMSPVA_EMAIL_T", "50")
s = os.environ.get("SMSPVA_EMAIL_S", "0")
sq = os.environ.get("SMSPVA_EMAIL_SQ", "verification")
query = {
"method": "get_mails",
"orderid": orderid,
"t": t,
"s": s,
"sq": sq
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_mails',
'orderid' => $orderid,
't' => $t,
's' => $s,
'sq' => $sq
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
t := env("SMSPVA_EMAIL_T", "50")
s := env("SMSPVA_EMAIL_S", "0")
sq := env("SMSPVA_EMAIL_SQ", "verification")
query := url.Values{}
query.Set("method", "get_mails")
query.Set("orderid", orderid)
query.Set("t", t)
query.Set("s", s)
query.Set("sq", sq)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var t = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_T") ?? "50";
var s = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_S") ?? "0";
var sq = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_SQ") ?? "verification";
var query = new Dictionary {
["method"] = "get_mails",
["orderid"] = orderid,
["t"] = t,
["s"] = s,
["sq"] = sq
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
String t = env("SMSPVA_EMAIL_T", "50");
String s = env("SMSPVA_EMAIL_S", "0");
String sq = env("SMSPVA_EMAIL_SQ", "verification");
Map query = new LinkedHashMap<>();
query.put("method", "get_mails");
query.put("orderid", orderid);
query.put("t", t);
query.put("s", s);
query.put("sq", sq);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": [
{
"id": 6,
"sender": "noreply@example.com",
"subject": "Verification code",
"preview": "Your code: 12345",
"addedAt": "2026-10-22T10:00:00.000Z"
}
]
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**Empty result**
```json
{
"status": 1,
"data": []
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].id`** | integer | 邮件 ID,作为 **`emailid`** 传给 get_mail_body。 |
| **`data[].sender`** | string | 发件人地址。 |
| **`data[].subject`** | string | 邮件主题。 |
| **`data[].preview`** | string | 邮件预览。 |
| **`data[].addedAt`** | string | 邮件时间。 (**`format: "date-time"`**) |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 有效订单 (/zh/docs/email/orders)
GET{"https://smspva.com/api/rent_email.php?method=get_orders"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "get_orders" | 要调用的方法。 |
## 使用说明 [#使用说明]
查看有效邮箱租赁、邮件数量和可用别名。此响应的邮箱地址字段为 **`address`**,而[创建租赁](/zh/docs/email/create)中叫 **`email`**。
用订单 ID [读取邮件](/zh/docs/email/messages)或[延期](/zh/docs/email/prolong)。Gmail 订单可能包含 **`aliases[].id`**,可用于[购买别名访问权](/zh/docs/email/buy-alias);Outlook 不支持别名。已结束的租赁见[归档订单](/zh/docs/email/archived)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_orders" \
--data-urlencode "apikey=$SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "get_orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "get_orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
query = {
"method": "get_orders"
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_orders'
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
query := url.Values{}
query.Set("method", "get_orders")
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var query = new Dictionary {
["method"] = "get_orders"
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
Map query = new LinkedHashMap<>();
query.put("method", "get_orders");
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": [
{
"id": 123456,
"address": "mailbox@outlook.com",
"scode": "twitter",
"pcode": "outlookcom",
"expireDate": 1855324800,
"mesCount": 1,
"aliases": [],
"sname": "Twitter"
},
{
"id": 123457,
"address": "sample@gmail.com",
"scode": "twitter",
"pcode": "gmailcom",
"expireDate": 1855324800,
"mesCount": 0,
"aliases": [
{
"id": 88,
"address": "sam.ple@gmail.com",
"mesCount": 1,
"isPaid": false
}
],
"sname": "Twitter"
}
]
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].id`** | integer | 订单 ID。 |
| **`data[].address`** | string | 邮箱地址,在 create_order 响应中此字段名为 email。 |
| **`data[].scode`** | string | 服务代码。 |
| **`data[].pcode`** | string | 供应商代码。 |
| **`data[].expireDate`** | integer | 租赁到期时间,Unix 时间戳,单位为秒。 |
| **`data[].mesCount`** | integer | 邮件数量。 |
| **`data[].aliases`** | array<object> | |
| **`data[].aliases[].id`** | integer | 已有别名 ID,作为 **`aliasid`** 传入。 |
| **`data[].aliases[].address`** | string | 别名邮箱地址。 |
| **`data[].aliases[].mesCount`** | integer | 该别名的邮件数量。 |
| **`data[].aliases[].isPaid`** | boolean | 该别名的访问权是否已付费。 |
| **`data[].sname`** | string | 服务显示名称。 |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 延长租赁 (/zh/docs/email/prolong)
GET{"https://smspva.com/api/rent_email.php?method=prolong_order"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "prolong_order" | 要调用的方法。 |
| **`orderid`** | query | integer | 是 | 123456 | 按所调用方法,从 Create Order、Active Orders 或 Archived Orders 获取订单 ID。 |
| **`dtype`** | query | string | 是 | "week" | 租赁单位:day = 1 天,week = 7 天,month = 30 天。 |
| **`dcount`** | query | integer | 是 | 1 | 租赁周期数,必须为正数。 |
## 使用说明 [#使用说明]
用[有效订单](/zh/docs/email/orders)中的 ID 延长租赁,费用从余额扣除。**`dcount`** 必须为正数;**`day`**、**`week`**、**`month`** 每单位分别为 **1**、**7**、**30** 天。
若服务配置了折扣,延期至少 **30 天**时适用。成功后请刷新有效订单查看新的到期时间,本响应不包含该时间。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=prolong_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID" \
--data-urlencode "dtype=${SMSPVA_EMAIL_DTYPE:-week}" \
--data-urlencode "dcount=${SMSPVA_EMAIL_DCOUNT:-1}"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const dtype = process.env.SMSPVA_EMAIL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_EMAIL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "prolong_order",
"orderid": orderid,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const dtype = process.env.SMSPVA_EMAIL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_EMAIL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "prolong_order",
"orderid": orderid,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
dtype = os.environ.get("SMSPVA_EMAIL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_EMAIL_DCOUNT", "1")
query = {
"method": "prolong_order",
"orderid": orderid,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'prolong_order',
'orderid' => $orderid,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
dtype := env("SMSPVA_EMAIL_DTYPE", "week")
dcount := env("SMSPVA_EMAIL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "prolong_order")
query.Set("orderid", orderid)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "prolong_order",
["orderid"] = orderid,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
String dtype = env("SMSPVA_EMAIL_DTYPE", "week");
String dcount = env("SMSPVA_EMAIL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "prolong_order");
query.put("orderid", orderid);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": {
"id": 123456,
"email": "mailbox@outlook.com",
"service": "Twitter"
}
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | object | |
| **`data.id`** | integer | 订单 ID。 |
| **`data.email`** | string | 邮箱地址。 |
| **`data.service`** | string | 服务显示名称,并非服务代码。 |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 供应商 (/zh/docs/email/providers)
GET{"https://smspva.com/api/rent_email.php?method=get_providers"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
## 身份验证 [#身份验证]
调用此方法无需 API 密钥。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "get_providers" | 要调用的方法。 |
## 使用说明 [#使用说明]
获取已启用的邮箱供应商,用其 **`pcode`** 构建选择列表。请定期刷新,避免固定保存代码。供应商已启用,并不代表每个服务都有可用邮箱。
在查询[服务及价格](/zh/docs/email/services)、[余量](/zh/docs/email/counts)和[创建订单](/zh/docs/email/create)时,请使用同一 **`pcode`**。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_providers"
```
```js
const query = new URLSearchParams({
"method": "get_providers"
});
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
const query = new URLSearchParams({
"method": "get_providers"
});
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
query = {
"method": "get_providers"
}
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_providers'
];
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
query := url.Values{}
query.Set("method", "get_providers")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var query = new Dictionary {
["method"] = "get_providers"
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
Map query = new LinkedHashMap<>();
query.put("method", "get_providers");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": [
{
"id": 2,
"pcode": "gmailcom",
"name": "Gmail"
},
{
"id": 6,
"pcode": "outlookcom",
"name": "Microsoft Outlook"
}
]
}
```
**错误**
```json
{
"status": 0,
"msg": "Provider not found"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].id`** | integer | 供应商 ID。 |
| **`data[].pcode`** | string | 用于筛选和创建订单的供应商代码。 |
| **`data[].name`** | string | 显示名称。 |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 供应商与服务 (/zh/docs/email/reference-data)
选择供应商,查看其服务、日价和可用邮箱。选择**全部供应商**时,会合计已启用供应商,并在请求中省略 **`pcode`**。价格为 USD/天,只有 Gmail 支持别名访问。
打开或返回页面、切换供应商时会刷新;页面可见时每**分钟**更新。余量最多缓存 **15 秒**。数量响应中缺少某服务时,其余量为零。查询可用量不会预留邮箱。
# 恢复费用 (/zh/docs/email/restoration-cost)
GET{"https://smspva.com/api/rent_email.php?method=calc_restore_order"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "calc_restore_order" | 要调用的方法。 |
| **`orderid`** | query | integer | 是 | 123456 | 按所调用方法,从 Create Order、Active Orders 或 Archived Orders 获取订单 ID。 |
## 使用说明 [#使用说明]
查询[归档订单](/zh/docs/email/archived)当前的恢复费用。**`data`** 为 USD 金额,类型是数字。
查询不会恢复租赁,也不会扣款。价格可能变化,请在[恢复租赁](/zh/docs/email/restore)前立即确认。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=calc_restore_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "calc_restore_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "calc_restore_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
query = {
"method": "calc_restore_order",
"orderid": orderid
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'calc_restore_order',
'orderid' => $orderid
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "calc_restore_order")
query.Set("orderid", orderid)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var query = new Dictionary {
["method"] = "calc_restore_order",
["orderid"] = orderid
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "calc_restore_order");
query.put("orderid", orderid);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": 0.7
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | number | 当前恢复费用,单位为 USD。 |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 恢复租赁 (/zh/docs/email/restore)
GET{"https://smspva.com/api/rent_email.php?method=restore_order"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 账户 API 密钥。读取邮件及管理租赁需要使用订单所属账户的密钥。 |
| **`method`** | query | string | 是 | "restore_order" | 要调用的方法。 |
| **`orderid`** | query | integer | 是 | 123456 | 按所调用方法,从 Create Order、Active Orders 或 Archived Orders 获取订单 ID。 |
## 使用说明 [#使用说明]
恢复归档租赁。先从[归档订单](/zh/docs/email/archived)获取 ID,并查询[恢复费用](/zh/docs/email/restoration-cost);本请求会从余额扣除该费用。
不能自定义恢复时长。成功后,请刷新[有效订单](/zh/docs/email/orders)查看当前详情。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_EMAIL_ORDER_ID`**: **`orderid`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_EMAIL_ORDER_ID:?Set SMSPVA_EMAIL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=restore_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "orderid=$SMSPVA_EMAIL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const orderid = required("SMSPVA_EMAIL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_order",
"orderid": orderid
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
orderid = os.environ["SMSPVA_EMAIL_ORDER_ID"]
query = {
"method": "restore_order",
"orderid": orderid
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'restore_order',
'orderid' => $orderid
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
orderid := env("SMSPVA_EMAIL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "restore_order")
query.Set("orderid", orderid)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var orderid = Required("SMSPVA_EMAIL_ORDER_ID");
var query = new Dictionary {
["method"] = "restore_order",
["orderid"] = orderid
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String orderid = env("SMSPVA_EMAIL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "restore_order");
query.put("orderid", orderid);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": {
"id": 123455,
"email": "archived@outlook.com",
"service": "Twitter"
}
}
```
**错误**
```json
{
"status": 0,
"msg": "Incorrect apikey"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | object | |
| **`data.id`** | integer | 订单 ID。 |
| **`data.email`** | string | 邮箱地址。 |
| **`data.service`** | string | 服务显示名称,并非服务代码。 |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 服务与价格 (/zh/docs/email/services)
GET{"https://smspva.com/api/rent_email.php?method=get_data"}
发送 **GET** 请求后,即使 HTTP 为 **200**,也请检查 **`status`**:**1** 成功,**0** 失败,创建租赁时的 **2** 表示暂无邮箱。错误详情可能在 **`msg`**、**`errormsg`** 和 **`errorid`** 中。
## 身份验证 [#身份验证]
调用此方法无需 API 密钥。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "get_data" | 要调用的方法。 |
| **`pcode`** | query | string | 否 | "outlookcom" | Get Providers 返回的供应商代码。接受全部供应商时完全省略此参数,不要传空值或 null。 |
## 使用说明 [#使用说明]
查看服务、日价和邮箱余量。传入[供应商](/zh/docs/email/providers)的 **`pcode`** 可按供应商筛选,省略则合计已启用供应商。用服务的 **`scode`** [创建租赁](/zh/docs/email/create)。
价格单位为 USD。租期至少 **30 天**时适用 **`months_discount`**。仅 Gmail 支持别名。切换供应商后,请刷新[余量](/zh/docs/email/counts)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/email/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
设置 **`SMSPVA_EMAIL_PCODE`** 选择当前供应商;未设置或空值时完全省略 **`pcode`**。请使用实时列表中的代码。
```bash
provider_args=()
if [ -n "${SMSPVA_EMAIL_PCODE:-}" ]; then provider_args=(--data-urlencode "pcode=$SMSPVA_EMAIL_PCODE"); fi
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent_email.php" \
--data-urlencode "method=get_data" \
"${provider_args[@]}"
```
```js
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const query = new URLSearchParams({
"method": "get_data",
"pcode": pcode
});
if (!pcode) query.delete("pcode");
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```ts
export {};
const pcode = process.env.SMSPVA_EMAIL_PCODE ?? "";
const query = new URLSearchParams({
"method": "get_data",
"pcode": pcode
});
if (!pcode) query.delete("pcode");
const response = await fetch("https://smspva.com/api/rent_email.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; errormsg?: string; errorid?: number; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? result.errormsg ?? "Email request failed"} (status=${result.status}, errorid=${result.errorid ?? "none"})`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
pcode = os.environ.get("SMSPVA_EMAIL_PCODE", "")
query = {
"method": "get_data",
"pcode": pcode
}
if not pcode:
del query["pcode"]
request = Request("https://smspva.com/api/rent_email.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', result.get('errormsg', 'Email request failed'))} (status={result.get('status')}, errorid={result.get('errorid')})")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_data',
'pcode' => $pcode
];
if ($pcode === '') unset($query['pcode']);
$curl = curl_init("https://smspva.com/api/rent_email.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? $result['errormsg'] ?? 'Email request failed') . ' status=' . ($result['status'] ?? 'missing') . ' errorid=' . ($result['errorid'] ?? 'none'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
pcode := os.Getenv("SMSPVA_EMAIL_PCODE")
query := url.Values{}
query.Set("method", "get_data")
query.Set("pcode", pcode)
if pcode == "" { query.Del("pcode") }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent_email.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
Errormsg string `json:"errormsg"`
Errorid int `json:"errorid"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: status=%d msg=%s errormsg=%s errorid=%d", response.StatusCode, result.Status, result.Msg, result.Errormsg, result.Errorid))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var pcode = Environment.GetEnvironmentVariable("SMSPVA_EMAIL_PCODE") ?? "";
var query = new Dictionary {
["method"] = "get_data",
["pcode"] = pcode
};
if (string.IsNullOrEmpty(pcode)) query.Remove("pcode");
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent_email.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Private Email examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String pcode = env("SMSPVA_EMAIL_PCODE", "");
Map query = new LinkedHashMap<>();
query.put("method", "get_data");
query.put("pcode", pcode);
if (pcode.isEmpty()) query.remove("pcode");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent_email.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.toString());
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
HTTP 为 200 时仍需检查 status;示例数值仅供参考。
**application/json**
**成功响应示例**
```json
{
"status": 1,
"data": [
{
"count": 40,
"scode": "twitter",
"sname": "Twitter",
"price": 0.1,
"alias_price": 0.25,
"icon": "/templates/SMSv1EN/images/ico/twitter.png",
"months_discount": 20
}
]
}
```
**错误**
```json
{
"status": 0,
"msg": "Provider not found"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [1]`**) |
| **`data`** | array<object> | |
| **`data[].count`** | integer | 可用邮箱数量。 |
| **`data[].scode`** | string | 创建订单使用的服务代码。 |
| **`data[].sname`** | string | 服务显示名称。 |
| **`data[].price`** | number | 租赁日价,单位为 USD。 |
| **`data[].alias_price`** | number | 别名访问价格,仅 Gmail 支持别名。 |
| **`data[].icon`** | string | 服务图标路径。 |
| **`data[].months_discount`** | integer | 租期至少 30 天时的折扣百分比。 |
必填: **`status`**, **`data`**
**错误**
部分错误含 errorid 和 errormsg,其他错误仅有 msg。请检查响应中提供的全部错误字段。
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | (**`enum: [0]`**) |
| **`errorid`** | integer | 可选的结构化错误代码。 |
| **`errormsg`** | string | 可选的错误说明。 |
| **`msg`** | string | 错误信息。 |
## 相关指南 [#相关指南]
- [Private Email Rental API](/zh/docs/email)
- [供应商与服务](/zh/docs/email/reference-data)
- [邮箱租赁流程](/zh/docs/email/workflow)
- [错误](/zh/docs/email/errors)
- [OpenAPI 定义](/openapi/email.json)
# 邮箱租赁流程 (/zh/docs/email/workflow)
## 1. 选择供应商和服务 [#1-选择供应商和服务]
查询[供应商](/zh/docs/email/providers)、[服务及价格](/zh/docs/email/services)、[余量](/zh/docs/email/counts)。保持同一 **`pcode`**;接受任意供应商时完全省略,不能传空值或 null。余量最多缓存 15 秒,不代表预留。
## 2. 创建租赁 [#2-创建租赁]
用 **`scode`**、**`dtype`**、**`dcount`** [创建租赁](/zh/docs/email/create)。day/week/month 每单位为 1/7/30 天。30 天起按 **`months_discount`** 折扣。指定供应商无自动替换;**`status=2`** 表示无库存。
## 3. 保存订单信息 [#3-保存订单信息]
保存 **`data.id`**、email、**`pcode`**、**`expireDate`**。[有效订单](/zh/docs/email/orders) 的邮箱字段名为 address;到期时间为 Unix 秒。
## 4. 读取邮件 [#4-读取邮件]
用 **`orderid`** [列出邮件](/zh/docs/email/messages),t 为条数,s 为偏移,sq 搜索需 URL 编码。data=[] 为成功无结果。将邮件 id 作为 **`emailid`**,与父订单 **`orderid`** 一起[读取正文](/zh/docs/email/message-body)。正文 HTML 不可信,显示前应清理。
## 5. 使用 Gmail 别名 [#5-使用-gmail-别名]
仅 Gmail 支持别名。使用有效订单 aliases[].id [购买访问权](/zh/docs/email/buy-alias),无公开的别名生成接口。[别名邮件](/zh/docs/email/alias-messages) 仍传父订单 **`orderid`**。
## 6. 延期或取消 [#6-延期或取消]
[延期](/zh/docs/email/prolong) 后刷新有效订单查看到期时间。[取消](/zh/docs/email/cancel) 不保证退款。
## 7. 恢复归档租赁 [#7-恢复归档租赁]
在[归档](/zh/docs/email/archived) 找到订单,先查[当前恢复费用](/zh/docs/email/restoration-cost),再[恢复](/zh/docs/email/restore)。查费不扣款,恢复扣款。不接受自定义恢复时长,完成后刷新有效订单。
付费请求超时后先核对订单状态,再决定是否重试,避免重复购买或延期。
# 错误与限制 (/zh/docs/errors)
以各接口响应表为准。同一个 HTTP 状态在不同接口可能含义不同,不要用通常的 HTTP 含义替换本 API 定义。报告失败时保留 **`statusCode`**、**`error.type`** 和 **`error.description`**。
## 等待不是最终失败 [#等待不是最终失败]
Receive SMS 的 **202 / SMS_NOT_YET_RECEIVED** 使用 error 对象表示等待,这是有意设计。先识别此响应,再在订单期限内继续轮询,不要将所有 error 对象都视为最终失败。
## 限流与网络故障 [#限流与网络故障]
处理各接口文档定义的限流错误,包括存在时的 ACCESS_LIMITED。各接口的限流响应请以对应说明为准。超时、连接失败或非 JSON 响应不同于已确认的 API 错误。示例不自动重试;号码申请结果未知时应先检查当前订单。
## 响应索引 [#响应索引]
横线表示原文档未提供结构化错误类型示例。保留不同接口的错误类型和说明差异。
| HTTP | **`error.type`** | 说明 | 方法 |
| --- | --- | --- | --- |
| 400 | APIKEY_NOT_SET | 缺少 **`apikey`** 请求头、值为空或长度不正确。 | [查询余额](/zh/docs/api/balance), [用户信息](/zh/docs/api/userinfo) |
| 400 | APIKEY_NOT_SET | 未收到 API 密钥。 | [运营商](/zh/docs/api/operators), [接收质量指标](/zh/docs/api/conversions), [国家及运营商价格](/zh/docs/api/country-operator-prices) |
| 400 | APIKEY_NOT_SET | 缺少 **`apikey`** 请求头、值为空或不足 30 个字符。 | [消息类型设置](/zh/docs/api/country-service-settings) |
| 401 | USER_NOT_FOUND | 未找到此 API 密钥对应的账户。 | [消息类型设置](/zh/docs/api/country-service-settings) |
| 402 | RATELIMIT_EXCEED | 请求频率超限;此 API 使用 HTTP 402 表示该错误。 | [消息类型设置](/zh/docs/api/country-service-settings) |
| 403 | USER_BANNED | 账户已被封禁。 | [消息类型设置](/zh/docs/api/country-service-settings) |
| 500 | SERVER_ERROR | 服务器内部错误;启用错误详情时,说明可能包含具体异常。 | [消息类型设置](/zh/docs/api/country-service-settings) |
| 402 | RATELIMIT_EXCEED | 已超过 API 请求频率限制。 | [所有号码余量](/zh/docs/api/countnumbers) |
| 405 | INVALID_PARAMS | country 或 service 参数不正确。 | [服务价格](/zh/docs/api/service-price) |
| 405 | INVALID_PARAMS | 参数不正确 | [按国家查询服务价格](/zh/docs/api/service-prices), [获取号码](/zh/docs/api/get-number), [按运营商获取号码](/zh/docs/api/get-number-by-operator), [接收短信](/zh/docs/api/receive-sms), [清除短信](/zh/docs/api/clear-sms), [停止接收短信](/zh/docs/api/stop-sms), [取消订单](/zh/docs/api/cancel-order) |
| 407 | LOW_BALANCE | 余额不足以接收所选国家和服务的短信。 | [获取号码](/zh/docs/api/get-number) |
| 411 | ACCESS_LIMITED | karma 过低或请求过于频繁,API 访问受限。 | [获取号码](/zh/docs/api/get-number), [接收短信](/zh/docs/api/receive-sms), [停止接收短信](/zh/docs/api/stop-sms), [取消订单](/zh/docs/api/cancel-order), [屏蔽号码](/zh/docs/api/block-number) |
| 500 | NUMBER_FETCH_FAIL | 未能获取号码。 | [获取号码](/zh/docs/api/get-number) |
| 501 | PRICE_FETCH_FAIL | 未找到号码。 | [获取号码](/zh/docs/api/get-number) |
| 502 | NUMBER_NOT_FOUND | 未找到号码。 | [获取号码](/zh/docs/api/get-number) |
| 503 | SERVER_BUSY | 服务器繁忙,请稍后再试。 | [获取号码](/zh/docs/api/get-number) |
| 407 | — | 余额不足以接收所选国家和服务的短信。 | [按运营商获取号码](/zh/docs/api/get-number-by-operator) |
| 411 | — | karma 过低或请求过于频繁,API 访问受限。 | [按运营商获取号码](/zh/docs/api/get-number-by-operator) |
| 500 | — | 未能获取号码。 | [按运营商获取号码](/zh/docs/api/get-number-by-operator) |
| 501 | — | 未找到号码。 | [按运营商获取号码](/zh/docs/api/get-number-by-operator) |
| 502 | — | 未找到号码。 | [按运营商获取号码](/zh/docs/api/get-number-by-operator), [号码状态](/zh/docs/api/number-status) |
| 503 | — | 服务器繁忙,请稍后再试。 | [按运营商获取号码](/zh/docs/api/get-number-by-operator) |
| 406 | INVALID_ORDER_FORMAT | 订单 ID 格式不正确或未找到。 | [接收短信](/zh/docs/api/receive-sms) |
| 407 | LOW_BALANCE | 已收到短信,但余额不足以支付。 | [接收短信](/zh/docs/api/receive-sms) |
| 410 | ORDER_CLOSED | 订单已关闭,不可继续使用。 | [接收短信](/zh/docs/api/receive-sms) |
| 500 | SMS_FETCH_FAIL | 未能获取短信。 | [接收短信](/zh/docs/api/receive-sms) |
| 501 | SERVER_FAIL | 服务器未能处理请求。 | [接收短信](/zh/docs/api/receive-sms), [当前订单](/zh/docs/api/orders), [清除短信](/zh/docs/api/clear-sms), [停止接收短信](/zh/docs/api/stop-sms), [屏蔽号码](/zh/docs/api/block-number) |
| 503 | SERVER_BUSY | 服务器负载过高,请稍后再试。 | [接收短信](/zh/docs/api/receive-sms), [当前订单](/zh/docs/api/orders), [停止接收短信](/zh/docs/api/stop-sms), [取消订单](/zh/docs/api/cancel-order), [屏蔽号码](/zh/docs/api/block-number) |
| 405 | INVALID_NUMBER_FORMAT | 号码格式不正确 | [号码状态](/zh/docs/api/number-status) |
| 406 | ORDER_NOT_FOUND | 订单 ID 格式不正确或未找到。 | [号码状态](/zh/docs/api/number-status), [停止接收短信](/zh/docs/api/stop-sms), [取消订单](/zh/docs/api/cancel-order), [屏蔽号码](/zh/docs/api/block-number) |
| 500 | SERVER_ERROR | 服务器内部错误,说明可能包含诊断详情。 | [号码状态](/zh/docs/api/number-status) |
| 501 | — | 服务器未能处理请求。 | [号码状态](/zh/docs/api/number-status) |
| 503 | — | 服务器负载过高,请稍后再试。 | [号码状态](/zh/docs/api/number-status) |
| 504 | — | **`av2.resp.504.desc`**:原始文档未提供此响应的完整说明。 | [号码状态](/zh/docs/api/number-status) |
| 404 | NO_SMS_TO_CLEAN | 尚未收到短信,或有待付费短信。 | [清除短信](/zh/docs/api/clear-sms) |
| 406 | ORDER_NOT_FOUND | 未找到订单。 | [清除短信](/zh/docs/api/clear-sms) |
| 503 | SERVER_BUSY | 尚未收到短信,或有待付费短信。 | [清除短信](/zh/docs/api/clear-sms) |
| 501 | SERVER_BUSY | 服务器未能处理请求。 | [取消订单](/zh/docs/api/cancel-order) |
| 405 | INVALID_PARAMS | 号码格式不正确 | [屏蔽号码](/zh/docs/api/block-number) |
# 代码示例 (/zh/docs/examples)
每个 [Activation V2 接口](/zh/docs/api)均提供 **cURL、JavaScript、TypeScript、Python、PHP、Go、C# 和 Java** 示例。示例遵循文档中的 HTTP 方法和 **`apikey`** 请求头,不依赖 SMSPVA SDK。
## 运行环境 [#运行环境]
| 示例 | 环境 | 运行 |
| --- | --- | --- |
| cURL | cURL 7.76+,macOS、Linux 或 WSL 的 POSIX shell | 在 shell 中执行 |
| JavaScript | Node.js 22.16+ | node Example.mjs |
| TypeScript | 含 Node 类型的 ESM 项目 | Example.mts;使用 NodeNext/ES2022 编译或现有 TS 执行器 |
| Python | Python 3.10+,标准库 | python Example.py |
| PHP | PHP 8.1+,ext-curl | php Example.php |
| Go | Go 1.20+,标准库 | go run Example.go |
| C# | .NET 8+ 控制台项目 | 写入 Program.cs;dotnet run |
| Java | JDK 11+,标准库 | java Example.java |
Java 标准库不包含 JSON 解析器,因此示例保留原始 JSON,请用应用已有的 JSON 库读取字段。其他语言示例会解析响应。JavaScript 和 TypeScript 用于服务器上的 Node.js,不是浏览器代码。
## 环境变量 [#环境变量]
```text
# macOS / Linux / WSL
export SMSPVA_API_KEY="YOUR_API_KEY"
```
```text
# PowerShell
$env:SMSPVA_API_KEY = "YOUR_API_KEY"
$env:SMSPVA_ORDER_ID = "123456" # 替换为实际订单 ID
```
订单接口要求 **SMSPVA_ORDER_ID**。号码状态接口要求 **SMSPVA_NUMBER**,不含国家电话区号。国家、服务和运营商使用原文档中的示例默认值,可以修改代码或设置 **SMSPVA_COUNTRY**、**SMSPVA_SERVICE**、**SMSPVA_OPERATOR**。cURL 中的代码为字面值,请直接修改。
实际代码参见[国家和服务](/zh/docs/reference-data)及[运营商](/zh/docs/api/operators)。支持 voice 的示例使用 **voice=0**。来电显示改为 1,语音改为 2,并先检查[权限设置](/zh/docs/message-types)。
Receive SMS 另支持可选请求头 **partnerkey**,用于成功接收短信时的推荐记账。
## 响应与重试 [#响应与重试]
示例设置 30 秒客户端超时,不自动重试。先识别 202 / SMS_NOT_YET_RECEIVED,再处理一般错误。cURL 输出响应体,Java 保留原始 JSON 供应用解析。
重复等待请求参见[轮询指南](/zh/docs/activation-workflow)。购买结果不明时,先查看当前订单再决定是否重新申请。
# 欢迎使用 SMSPVA (/zh/docs)
## 构建第一个集成 [#构建第一个集成]
从 **Activation V2** 开始:查询余额、理解响应,然后再接入订单流程。
配置 API 密钥并发送第一个请求。
全部 20 个接口及八种语言示例。
全部 22 个租赁方法、实时列表和完整租赁流程。
全部 14 个接口、实时供应商列表及八种语言示例。
选择 Python、JS/TS、PHP、Go、C# 或 Java SDK。
连接本地 MCP 服务,使用全部 56 个 API 工具。
## 选择正确的 API [#选择正确的-api]
| API 类别 | 用途 | 文档 |
| --- | --- | --- |
| Activation V2 | 电话号码激活流程 | [完整参考:20 个接口](/zh/docs/api) |
| 号码租赁 | 较长时间的号码租赁 | [完整参考:22 个接口](/zh/docs/rental) |
| 私人邮箱租赁 | 邮箱租赁与收件 | [现有参考](/zh/docs/email) |
不同 API 类别使用不同的身份验证和响应格式。请遵循对应类别的服务器地址、凭据格式和方法说明。
## 这里有哪些内容 [#这里有哪些内容]
文档涵盖 Activation V2、号码租赁和私人邮箱租赁,提供实时基础数据及八种语言示例。先阅读所需 API 的使用流程,再查看各接口的参数和响应。已发布的 Alpha SDK 包括 [PyPI 上的 Python](https://pypi.org/project/smspva-sdk/)、[npm 上的 JavaScript/TypeScript](https://www.npmjs.com/package/smspva-sdk)、[Packagist 上的 PHP](https://packagist.org/packages/smspva/sdk)、[pkg.go.dev 上的 Go](https://pkg.go.dev/github.com/SMSPVA/smspva-go)、[NuGet 上的 C#/.NET](https://www.nuget.org/packages/Smspva.Sdk/0.1.0-alpha.1) 和 [Maven Central 上的 Java](https://central.sonatype.com/artifact/com.smspva/smspva-sdk/0.1.0-alpha.1)。两个 MCP 服务仍为本地 Alpha 版本。
# MCP 与 AI 工具 (/zh/docs/mcp)
## 连接你的 AI 助手 [#连接你的-ai-助手]
将 SMSPVA 文档 MCP 添加到 AI 客户端,即可在开发时查询 API 方法和代码示例。服务由 SMSPVA 托管,无需下载项目、安装 Node.js 或 Docker,也无需提供 SMSPVA API 密钥。
在支持 **Streamable HTTP** 远程 MCP 的客户端中,填写以下完整地址:
```text
https://mcp.smspva.com/docs
```
| 设置 | 值 |
| --- | --- |
| 服务名称 | **`smspva_docs`** |
| 传输方式 | **Streamable HTTP**;部分客户端显示为 **HTTP** |
| 服务地址 | **`https://mcp.smspva.com/docs`** |
| 身份验证 | 无;不需要 API 密钥或 OAuth 登录 |
| 文档语言 | English **`en`**、español **`es`**、中文 **`zh`** |
在客户端的 MCP 设置中,使用上述信息添加远程服务,保存后启用或重新连接。若出现服务信任提示,请先查看内容再确认。将下方示例合并到现有配置中,不要覆盖其他服务。
此 MCP 只搜索和读取公开文档,并返回代码示例。它不能购买号码、读取你的私人短信或邮件,也不能修改账户。API MCP 是另一项独立服务,详见本页后半部分。两者均不包含 Alternative API。
## Codex [#codex]
在 Codex 的 **`config.toml`** 中添加以下配置。如果已有指向本地进程的 **`mcp_servers.smspva_docs`**,请将该条目替换为 URL 配置,不要重复添加同名表。保留独立的 API 连接 **`mcp_servers.smspva`**。
```toml
[mcp_servers.smspva_docs]
url = "https://mcp.smspva.com/docs"
startup_timeout_sec = 20
tool_timeout_sec = 45
```
重新连接服务或重启 Codex 会话以应用更改。该条目不需要 **`command`**、**`args`**、**`env`** 或令牌。配置文件位置及客户端操作方式见 [Codex 官方 MCP 指南](https://learn.chatgpt.com/docs/extend/mcp?surface=cli)。
## Cursor [#cursor]
将以下配置添加到项目内的 **`.cursor/mcp.json`**,或用户目录中的 **`~/.cursor/mcp.json`**:
```json
{
"mcpServers": {
"smspva_docs": {
"url": "https://mcp.smspva.com/docs"
}
}
}
```
在 Cursor 的 MCP 设置中启用服务。更多说明见 [Cursor 官方 MCP 指南](https://prod.cursor.com/docs/mcp)。
## VS Code [#vs-code]
在命令面板运行 **MCP: Add Server**,选择 **HTTP**,输入 **`https://mcp.smspva.com/docs`**,并将服务标识设为 **`smspva_docs`**。选择配置保存位置,并查看服务信任提示。工作区 **`.vscode/mcp.json`** 的等效配置如下:
```json
{
"servers": {
"smspva_docs": {
"type": "http",
"url": "https://mcp.smspva.com/docs"
}
}
}
```
配置格式可能因所选代理提供方而异。请参阅 [VS Code 配置指南](https://code.visualstudio.com/docs/agent-customization/mcp-servers)和[配置参考](https://code.visualstudio.com/docs/agents/reference/mcp-configuration)。
## 在对话中试用 [#在对话中试用]
连接后,请明确让 AI 助手使用 SMSPVA 文档 MCP。例如:
- “使用 SMSPVA 文档 MCP,给我一个查询余额的 Python 示例,用中文解释,不要执行代码。”
- “在西班牙文文档中查找 Private Email 的供应商查询方法,并返回 JavaScript 请求示例。”
- “阅读中文版 Rental 流程,解释如何激活租赁并获取消息。”
连接成功后,应能看到四个工具:**`smspva_docs_search`**、**`smspva_docs_read_page`**、**`smspva_docs_get_examples`** 和 **`smspva_docs_list_pages`**。如果助手看不到这些工具,请确认当前会话已启用该服务,且组织策略允许连接。
服务包含 228 页文档,每种语言 76 页,覆盖全部 56 个已批准 API 方法。托管文档包由 SMSPVA 维护,用户无需自行构建。每次返回结果都会标明文档快照。当前价格和余量仍需通过 API 或本网站的实时列表查询。
## 连接问题排查 [#连接问题排查]
- 使用完整地址 **`https://mcp.smspva.com/docs`**,保留 **`/docs`**。不要改成首页,也不要添加 **`/sse`**。
- 在浏览器直接打开 **`/docs`** 时返回 **`405`** 可能是正常现象:它是协议端点,不是网页。请通过 MCP 客户端测试连接。
- 浏览器内运行的客户端收到 **`403`**,可能是其 **`Origin`** 不在允许列表中。CORS 通配符不会绕过服务的 Origin 检查。请使用原生客户端,或向 SMSPVA 支持团队提供客户端名称和完整错误信息。
- 收到 **`429`** 时,请等待后再重试。遇到超时或 **`503`**,稍后重新连接,并检查网络及组织策略。反复添加同一服务无法解决这些问题。
- 不要向此文档端点发送 SMSPVA 密钥。连接不需要购买服务、访问账户或授权执行示例。
## 搜索、阅读与获取示例 [#搜索阅读与获取示例]
请明确指定 **`locale`**:**`en`**、**`es`** 或 **`zh`**。服务会使用该语言的页面和示例,不会自动切换语言,也不会翻译代码。页面标识在三种语言中保持一致,例如 **`api/balance`**、**`rental/default-services`**、**`email/providers`**、**`sdks`** 和 **`index`**。
| 工具 | 用途 |
| --- | --- |
| **`smspva_docs_search`** | 在选定的 **`locale`** 中搜索 **`query`**,可按 **`section`** 筛选并设置 **`limit`** |
| **`smspva_docs_read_page`** | 以 Markdown 读取 **`page`**,长页面可使用 **`offset`** 和 **`max_chars`** 分段读取 |
| **`smspva_docs_get_examples`** | 获取 **`page`** 中完整的代码块,可按 **`language`** 或 **`kind`** 筛选,并用 **`offset`** 和 **`limit`** 分页 |
| **`smspva_docs_list_pages`** | 浏览指定 **`locale`** 的页面标识,支持 **`section`** 筛选、**`offset`** 和 **`limit`** 分页 |
**`section`** 可选 **`activation`**、**`rental`**、**`email`** 或 **`guides`**。获取请求示例时,**`language`** 可选 **`curl`**、**`javascript`**、**`typescript`**、**`python`**、**`php`**、**`go`**、**`csharp`** 或 **`java`**;也可以获取 JSON 响应、shell 环境设置等其他代码块。**`kind`** 用于区分 **`request`**、**`response`** 和 **`guide`** 示例。
以下内容是 MCP **`tools/call`** 请求的参数。搜索西班牙文 Activation 参考:
```json
{
"name": "smspva_docs_search",
"arguments": {"query": "saldo", "locale": "es", "section": "activation", "limit": 5}
}
```
读取中文版余额页面:
```json
{
"name": "smspva_docs_read_page",
"arguments": {"page": "api/balance", "locale": "zh", "max_chars": 6000}
}
```
获取英文页面中的 Python 请求示例:
```json
{
"name": "smspva_docs_get_examples",
"arguments": {"page": "api/balance", "locale": "en", "language": "python", "kind": "request", "limit": 1}
}
```
代码块直接取自选定页面。HTTP 方法、参数名、响应码及重要警告的含义均保持不变。长页面或较多示例可以根据结果中的分页信息继续读取。
## API MCP:调用 SMSPVA [#api-mcp调用-smspva]
本地 Alpha 版本已将 Activation V2、Rental 和 Private Email 的全部 56 个方法开放为 MCP 工具。它需要 Node.js 22.16 或更高版本,通过 stdio 连接 MCP 客户端,无需 Docker。
当前版本以本地进程运行,尚未提供远程 HTTP 端点或 OAuth,也未发布到软件包仓库、GitHub 或 MCP 目录。Alternative API 不包含在内。
## 构建与连接 API 服务 [#构建与连接-api-服务]
在项目目录中执行:
```sh
cd sdk/javascript
npm ci
cd ../../mcp
npm ci
npm run build
```
在客户端的 MCP 配置中添加服务。将绝对路径替换为本机 **`mcp/src/cli.mjs`** 的实际位置:
```json
{
"mcpServers": {
"smspva": {
"command": "node",
"args": ["/absolute/path/to/mcp/src/cli.mjs"],
"env": {
"SMSPVA_API_KEY": "YOUR_API_KEY",
"SMSPVA_READ_ONLY": "true"
}
}
}
}
```
请将真实的 **`SMSPVA_API_KEY`** 保存在客户端的密钥存储或私有本地配置中,不要粘贴到聊天中,也不要作为工具参数传入。公开方法无需密钥;受保护的方法在未配置密钥时会返回验证错误。
示例启用了 **`SMSPVA_READ_ONLY`**,只开放 36 个只读工具。在此模式下,即使客户端知道另外 20 个工具的名称,服务也会拒绝调用它们。若要启用全部 56 个工具,可以删除该设置或将其设为 **`false`**。未设置时,默认开放全部 56 个工具。
## Codex:API 服务 [#codexapi-服务]
可将以下示例加入 Codex 的 **`config.toml`**,并使用 Node.js 22.16+。启动 Codex 前,请确保其环境中已有 **`SMSPVA_API_KEY`**。此示例不会安装服务。配置说明见 [OpenAI 官方文档](https://learn.chatgpt.com/docs/extend/mcp?surface=cli)。
```toml
[mcp_servers.smspva]
command = "node"
args = ["/absolute/path/to/mcp/src/cli.mjs"]
env_vars = ["SMSPVA_API_KEY"]
startup_timeout_sec = 20
tool_timeout_sec = 45
[mcp_servers.smspva.env]
SMSPVA_READ_ONLY = "true"
```
## 调用工具 [#调用工具]
工具名称采用 **`smspva__`** 格式,其中 API 类别为 **`activation`**、**`rental`** 或 **`email`**。参数名称与 API 参考保持一致。国家、服务、供应商、价格和余量查询会读取 API 的当前数据,不依赖软件包内置的固定列表。
下面是 MCP **`tools/call`** 请求的参数。查询账户余额:
```json
{
"name": "smspva_activation_get_balance",
"arguments": {}
}
```
读取当前 Email 供应商列表,无需发送 API 密钥:
```json
{
"name": "smspva_email_get_providers",
"arguments": {}
}
```
读取一条新收到的短信可能触发扣费。以下调用仅在关闭只读模式时可用。请使用账户中已有订单的 **`orderid`**,并仅在确定要获取该结果时调用:
```json
{
"name": "smspva_activation_receive_sms",
"arguments": {
"orderid": 12345
}
}
```
每次工具调用只发送一次 API 请求。服务不会自行创建订单、重试请求或在后台轮询。若要在客户端重复查询短信,请先阅读 [Activation 流程](/zh/docs/activation-workflow)。
## 结果、错误与费用 [#结果错误与费用]
调用成功时,工具会在 **`structuredContent`** 中返回原始 API 数据。HTTP **`202`** 和 **`SMS_NOT_YET_RECEIVED`** 仍表示正常的等待结果。创建 Email 订单时的 **`status=2`** 仍表示正常的无库存结果。HTTP 方法、参数名、响应码和响应值类型均遵循文档中的接口约定。
MCP 客户端还可以通过 **`smspva://contracts/activation`**、**`smspva://contracts/rental`** 和 **`smspva://contracts/email`** 读取随版本提供的 OpenAPI 接口定义,其中包含参数、响应结构和响应码。当前价格与余量应通过 API 工具查询。
工具错误使用 **`isError: true`** 和 **`structuredContent.error`**。API 错误保留 HTTP 状态、API 错误码和响应正文,但会隐藏其中出现的已配置账户密钥。**`SMSPVA_TIMEOUT_MS`** 默认为 **`30000`**,覆盖整个 HTTP 请求及响应正文的读取。
创建、延期、恢复或取消订单可能修改账户状态或产生费用,读取新的 Activation 短信也可能触发扣费。其中部分操作使用 GET。工具注解会将这些操作标记为会改变状态、可能具有破坏性的操作。注解只是提供给 MCP 客户端的提示,不是付款确认或访问控制。请在客户端中为账户配置合适的审批规则。
如果付费操作或修改状态的请求超时,其结果可能无法确定。重试前请先检查当前订单。返回的短信、邮件文本和 HTML 都是外部数据,不应当作指令执行。
## 以 Markdown 阅读文档 [#以-markdown-阅读文档]
无需 HTML 也可以读取本站内容:
- [文档索引](/llms.txt)
- [完整文档](/llms-full.txt)
- 各文档页面的 **Copy Markdown** 按钮。
上述文档 MCP 支持在客户端中搜索这些页面。也可以直接使用 [HTTP 示例](/zh/docs/quickstart)和 [SDK](/zh/docs/sdks)。
# 短信、来电显示与语音 (/zh/docs/message-types)
## 下单前选择类型 [#下单前选择类型]
| **`voice`** 查询值 | 结果 |
| --- | --- |
| 0 | 短信,默认 |
| 1 | 来电显示 |
| 2 | 语音电话 |
支持此参数的价格接口与号码申请应使用相同类型。[接收短信](/zh/docs/api/receive-sms)只使用订单 ID,不需要 **`voice`**。
## 权限规则 [#权限规则]
[消息类型设置](/zh/docs/api/country-service-settings)返回 **`country`**、**`service`**、**`operator`** 条件。空条件不限制匹配。非空匹配条件越多,规则优先级越高。应一起使用对应规则的三个标志;没有匹配规则时,三种类型默认均启用。
规则中的 **sms**、**caller**、**voice** 均使用 1 表示启用、0 表示禁用,不能与查询参数 **`voice=0`**/1/2 混淆。权限允许不代表存在可用号码。
## 结果格式 [#结果格式]
三种类型使用相同 JSON 结构。供应商 **`text`** 原样映射到 **data.sms.code**,**`sms`** 原样映射到 **data.sms.fullText**。
**`code`** 不保证是数字验证码。语音结果可能包含文字及录音链接。原文档中有些格式仅为示例或尚未确认,这些限定保留在响应示例中。来电显示使用占位符,因为供应商具体格式尚未确认。
三种类型均使用 **202 / SMS_NOT_YET_RECEIVED** 表示等待。参见[轮询指南](/zh/docs/activation-workflow)。
# 快速入门 (/zh/docs/quickstart)
## 1. 获取 API 密钥 [#1-获取-api-密钥]
登录 [SMSPVA](https://smspva.com),在账户菜单中打开 **Profile and ApiKey**。
将密钥保存在服务器环境变量中,让应用读取即可。不要把密钥写进公开的浏览器代码或提交到代码仓库。
```bash
export SMSPVA_API_KEY="YOUR_API_KEY"
```
```powershell
$env:SMSPVA_API_KEY = "YOUR_API_KEY"
```
## 2. 查询余额 [#2-查询余额]
Activation V2 的服务器地址是 **https://api.smspva.com**,使用 **apikey** 请求头。
cURL 示例使用 POSIX shell 语法,适用于 macOS、Linux 或 WSL。在 Windows 中,也可以从 PowerShell 运行 JavaScript 或 Python 示例。JavaScript 需要 Node.js 22.16+;Python 仅使用标准库,要求 Python 3.10+。
```bash
curl --fail-with-body --max-time 30 \
'https://api.smspva.com/activation/balance' \
--header "apikey: $SMSPVA_API_KEY"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
if (!apiKey) throw new Error("Set SMSPVA_API_KEY first");
const response = await fetch(
"https://api.smspva.com/activation/balance",
{
headers: { apikey: apiKey },
signal: AbortSignal.timeout(30_000),
},
);
const result = await response.json();
if (!response.ok || result.error || result.statusCode !== 200) {
throw new Error(
result.error?.description ?? `Request failed: ${response.status}`,
);
}
// The API returns balance as a string. Keep it for display.
console.log(result.data.balance);
```
```python
import json
import os
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen
api_key = os.environ["SMSPVA_API_KEY"]
request = Request(
"https://api.smspva.com/activation/balance",
headers={"apikey": api_key},
)
try:
with urlopen(request, timeout=30) as response:
result = json.load(response)
except HTTPError as error:
# HTTPError is also a readable response.
detail = error.read().decode("utf-8", errors="replace")
raise RuntimeError(f"HTTP {error.code}: {detail}") from error
except (URLError, TimeoutError) as error:
raise RuntimeError("Request could not be completed") from error
if result.get("error") or result.get("statusCode") != 200:
raise RuntimeError(result.get("error", result))
print(result["data"]["balance"])
```
## 3. 理解结果 [#3-理解结果]
```json
{
"statusCode": 200,
"data": { "balance": "10.50" }
}
```
实际响应会显示你自己账户的余额。**`balance`** 是**字符串**,显示金额时请保留这一类型。使用 **`data`** 前,先检查 HTTP 响应和 API 错误。
密钥缺失或长度不正确时,会返回 HTTP **400** 和 **`APIKEY_NOT_SET`**。请求超时则表示尚未确认 API 的处理结果。
## 下一步 [#下一步]
阅读[余额接口参考](/zh/docs/api/balance)、[SDK 计划](/zh/docs/sdks)或 [MCP 与 Markdown](/zh/docs/mcp)。
接下来阅读[激活流程](/zh/docs/activation-workflow)、[完整接口参考](/zh/docs/api)及[八种语言示例](/zh/docs/examples)。购买请求超时后不要自动重试:首次请求可能已经成功。
# 国家与服务 (/zh/docs/reference-data)
使用 Activation V2 时,请从这里选择 **`country`** 和 **`service`** 代码。申请号码前,再确认当前价格和余量。
打开页面时会加载列表,页面可见时每**五分钟**刷新。数据源也有五分钟缓存,因此新变更可能稍后才显示。号码租赁和邮箱租赁使用各自的列表。
## 相关指南 [#相关指南]
- [基础数据](/zh/docs/api/operators)
- [余量](/zh/docs/api/country-countnumbers)
- [价格](/zh/docs/api/service-price)
[实时 JSON](/reference-data.php)
# 激活租赁 (/zh/docs/rental/activate)
GET{"https://smspva.com/api/rent.php?method=activate"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "activate" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`id`** | query | integer | 是 | 1 | 订单 ID |
## 使用说明 [#使用说明]
向租赁号码发送短信前,先激活订单。使用[租赁订单](/zh/docs/rental/orders)中的 ID,激活后再检查 **`state`**。确认已激活后,通过[租赁短信](/zh/docs/rental/sms)读取消息。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=activate" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "activate",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "activate",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "activate",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'activate',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "activate")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "activate",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "activate");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": [
{
"id": 123
}
]
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | array<object> | |
| **`data[].id`** | integer | 订单 ID |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 向订单添加服务 (/zh/docs/rental/add-service)
GET{"https://smspva.com/api/rent.php?method=add_service_to_order"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "add_service_to_order" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`id`** | query | integer | 是 | 56547 | 订单 ID |
| **`service`** | query | string | 是 | "opt89" | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`pnumber`** | query | string | 是 | "79335445295" | 租赁号码,含国家区号,不带 +。 |
| **`rent_days`** | query | integer | 否 | 7 | 可选租赁天数;省略时,多数国家默认 7 天,加拿大默认 1 天。 |
## 使用说明 [#使用说明]
为已有租赁添加服务。在[租赁订单](/zh/docs/rental/orders)中获取 ID 和 **`pnumber`**,再按该国家查询[供应商数据](/zh/docs/rental/data-by-provider),确认新服务及价格。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
- **`SMSPVA_RENTAL_NUMBER`**: **`pnumber`**.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
: "${SMSPVA_RENTAL_NUMBER:?Set SMSPVA_RENTAL_NUMBER}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=add_service_to_order" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID" \
--data-urlencode "service=opt89" \
--data-urlencode "pnumber=$SMSPVA_RENTAL_NUMBER" \
--data-urlencode "rent_days=7"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt89";
const pnumber = required("SMSPVA_RENTAL_NUMBER");
const rent_days = process.env.SMSPVA_RENTAL_RENT_DAYS ?? "7";
const query = new URLSearchParams({
"method": "add_service_to_order",
"id": id,
"service": service,
"pnumber": pnumber,
"rent_days": rent_days
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt89";
const pnumber = required("SMSPVA_RENTAL_NUMBER");
const rent_days = process.env.SMSPVA_RENTAL_RENT_DAYS ?? "7";
const query = new URLSearchParams({
"method": "add_service_to_order",
"id": id,
"service": service,
"pnumber": pnumber,
"rent_days": rent_days
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
service = os.environ.get("SMSPVA_RENTAL_SERVICE", "opt89")
pnumber = os.environ["SMSPVA_RENTAL_NUMBER"]
rent_days = os.environ.get("SMSPVA_RENTAL_RENT_DAYS", "7")
query = {
"method": "add_service_to_order",
"id": id,
"service": service,
"pnumber": pnumber,
"rent_days": rent_days
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'add_service_to_order',
'id' => $id,
'service' => $service,
'pnumber' => $pnumber,
'rent_days' => $rent_days
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
service := env("SMSPVA_RENTAL_SERVICE", "opt89")
pnumber := env("SMSPVA_RENTAL_NUMBER", "")
rent_days := env("SMSPVA_RENTAL_RENT_DAYS", "7")
query := url.Values{}
query.Set("method", "add_service_to_order")
query.Set("id", id)
query.Set("service", service)
query.Set("pnumber", pnumber)
query.Set("rent_days", rent_days)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var service = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICE") ?? "opt89";
var pnumber = Required("SMSPVA_RENTAL_NUMBER");
var rent_days = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_RENT_DAYS") ?? "7";
var query = new Dictionary {
["method"] = "add_service_to_order",
["id"] = id,
["service"] = service,
["pnumber"] = pnumber,
["rent_days"] = rent_days
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
String service = env("SMSPVA_RENTAL_SERVICE", "opt89");
String pnumber = env("SMSPVA_RENTAL_NUMBER", null);
String rent_days = env("SMSPVA_RENTAL_RENT_DAYS", "7");
Map query = new LinkedHashMap<>();
query.put("method", "add_service_to_order");
query.put("id", id);
query.put("service", service);
query.put("pnumber", pnumber);
query.put("rent_days", rent_days);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"id": 4211321,
"pnumber": "37067181111",
"service": "opt95",
"until": 1771583220
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | 新增服务详情 |
| **`data.id`** | integer | 订单 ID |
| **`data.pnumber`** | string | 电话号码 |
| **`data.service`** | string | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`data.until`** | integer | 服务到期时间(Unix 时间戳) |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 加拿大 PayPal 天数 (/zh/docs/rental/canada-paypal-days)
GET{"https://smspva.com/api/rent.php?method=get_days_canada_paypal"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
调用此方法无需 API 密钥。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "get_days_canada_paypal" | 方法名称 |
## 使用说明 [#使用说明]
获取加拿大 PayPal 流程可用的租赁天数选项。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_days_canada_paypal"
```
```js
const query = new URLSearchParams({
"method": "get_days_canada_paypal"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const query = new URLSearchParams({
"method": "get_days_canada_paypal"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
query = {
"method": "get_days_canada_paypal"
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_days_canada_paypal'
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
query := url.Values{}
query.Set("method", "get_days_canada_paypal")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var query = new Dictionary {
["method"] = "get_days_canada_paypal"
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
Map query = new LinkedHashMap<>();
query.put("method", "get_days_canada_paypal");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": [
{
"Days": 30,
"Amount": 10
}
]
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | array<object> | 加拿大 PayPal 流程返回的租期条目。 |
| **`data[].Days`** | integer | 租赁天数。 |
| **`data[].Amount`** | integer | API 返回的该租期对应金额。 |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 可用号码数量 (/zh/docs/rental/count)
GET{"https://smspva.com/api/rent.php?method=getcount"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
调用此方法无需 API 密钥。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "getcount" | 方法名称 |
| **`country`** | query | string | 是 | "KZ" | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`dtype`** | query | string | 否 | "week" | 周期单位:week 或 month,省略时为 week。 |
| **`dcount`** | query | integer | 否 | 1 | 周期数;**`dtype`**=week 时表示周数,省略时为 1。 |
## 使用说明 [#使用说明]
查询指定 **`country`** 的租赁号码余量。省略时,**`dtype`** 默认为 **`week`**,**`dcount`** 默认为 **1**。服务名称与价格见[租赁数据](/zh/docs/rental/data),供应商明细见[按供应商查询余量](/zh/docs/rental/counts-by-provider)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getcount" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getcount",
"country": country,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getcount",
"country": country,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getcount",
"country": country,
"dtype": dtype,
"dcount": dcount
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getcount',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getcount")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getcount",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getcount");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | oneOf | 按服务划分的数量或总数,以后端响应为准。 |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 按服务查询国家 (/zh/docs/rental/countries-by-service)
GET{"https://smspva.com/api/rent.php?method=get_country_by_service"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
调用此方法无需 API 密钥。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "get_country_by_service" | 方法名称 |
| **`service`** | query | string | 是 | "opt20" | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`dtype`** | query | string | 是 | "week" | 周期单位:week 或 month |
| **`dcount`** | query | integer | 否 | 1 | 周期数;**`dtype`**=week 时表示周数,省略时为 1。 |
## 使用说明 [#使用说明]
按租赁 **`service`** 和 **`dtype`** 查询可用国家。选好后,通过[供应商数据](/zh/docs/rental/data-by-provider)比较供应商,保持服务和时长一致。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_country_by_service" \
--data-urlencode "service=opt20" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt20";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "get_country_by_service",
"service": service,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt20";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "get_country_by_service",
"service": service,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
service = os.environ.get("SMSPVA_RENTAL_SERVICE", "opt20")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "get_country_by_service",
"service": service,
"dtype": dtype,
"dcount": dcount
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_country_by_service',
'service' => $service,
'dtype' => $dtype,
'dcount' => $dcount
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
service := env("SMSPVA_RENTAL_SERVICE", "opt20")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "get_country_by_service")
query.Set("service", service)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var service = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICE") ?? "opt20";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "get_country_by_service",
["service"] = service,
["dtype"] = dtype,
["dcount"] = dcount
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String service = env("SMSPVA_RENTAL_SERVICE", "opt20");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "get_country_by_service");
query.put("service", service);
query.put("dtype", dtype);
query.put("dcount", dcount);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"": {
"service_name": "Fiverr",
"price": "0.20",
"procent_days": "30",
"procent": "30",
"day_step": "0.00",
"country": "KZ",
"phoneAmount": 79
}
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | |
| **`data.*`** | object | |
| **`data.*.service_name`** | string | |
| **`data.*.price`** | string | |
| **`data.*.procent_days`** | string | |
| **`data.*.procent`** | string | |
| **`data.*.day_step`** | string | |
| **`data.*.country`** | string | |
| **`data.*.phoneAmount`** | integer | |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 租赁国家 (/zh/docs/rental/countries)
GET{"https://smspva.com/api/rent.php?method=getcountries"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
调用此方法无需 API 密钥。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "getcountries" | 方法名称 |
## 使用说明 [#使用说明]
查询当前可租赁号码的国家。用返回的代码查询[租赁数据](/zh/docs/rental/data)或[供应商数据](/zh/docs/rental/data-by-provider),了解服务、价格和余量。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getcountries"
```
```js
const query = new URLSearchParams({
"method": "getcountries"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const query = new URLSearchParams({
"method": "getcountries"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
query = {
"method": "getcountries"
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getcountries'
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
query := url.Values{}
query.Set("method", "getcountries")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var query = new Dictionary {
["method"] = "getcountries"
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
Map query = new LinkedHashMap<>();
query.put("method", "getcountries");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": [
{
"name": "United States",
"code": "US",
"url_country_name": "united-states",
"rent_switch_type": "FAST",
"rent_avail_prolong": "1"
}
]
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | |
| **`data`** | array<object> | |
| **`data[].name`** | string | 国家名称 |
| **`data[].code`** | string | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`data[].url_country_name`** | string | 公开 URL 中使用的国家标识。 |
| **`data[].rent_switch_type`** | string | 该国家的租赁可用模式。 |
| **`data[].rent_avail_prolong`** | string | 该国家是否支持租赁延期。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 按供应商查询余量 (/zh/docs/rental/counts-by-provider)
GET{"https://smspva.com/api/rent.php?method=getCountWithProviders"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
**apikey** 查询参数可选。公共数据可省略;按文档传入后可获取账户相关数据或价格。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "getCountWithProviders" | 方法名称 |
| **`apikey`** | query | string | 否 | (optional) | 可选 API 密钥,传入后可能影响账户相关租赁数据。 |
| **`country`** | query | string | 是 | "KZ" | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`dtype`** | query | string | 否 | "week" | 周期单位:week 或 month,省略时为 week。 |
| **`dcount`** | query | integer | 否 | 1 | 周期数;**`dtype`**=week 时表示周数,省略时为 1。 |
## 使用说明 [#使用说明]
按服务和供应商比较余量。每个服务代码下,**`Amount`** 将供应商名称对应到数量,**`Total`** 为合计。服务代码和供应商名称会变化,请直接读取响应中的键。
即使 HTTP 为 **200**,也要检查 **`status`**。值为 **0** 时,错误原因见 **`msg`**。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
# Optional: add --data-urlencode "apikey=$SMSPVA_API_KEY" for account-specific data.
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getCountWithProviders" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getCountWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getCountWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ.get("SMSPVA_API_KEY")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getCountWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getCountWithProviders',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := os.Getenv("SMSPVA_API_KEY")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getCountWithProviders")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getCountWithProviders",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", "");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getCountWithProviders");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"opt48": {
"Amount": {
"Limbo_AT": 12,
"Tele2_AT": 1,
"yesss_AT": 69
},
"Total": 82
}
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | 各服务代码对应的供应商数量和合计。 |
| **`data.*`** | object | |
| **`data.*.Amount`** | object | 供应商名称及对应的可用号码数量。 |
| **`data.*.Amount.*`** | integer | |
| **`data.*.Total`** | integer | 该服务的可用号码总数。 |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 创建多服务租赁 (/zh/docs/rental/create-multi)
GET{"https://smspva.com/api/rent.php?method=create_multi"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "create_multi" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`dtype`** | query | string | 是 | "week" | 周期单位:week 或 month |
| **`dcount`** | query | integer | 是 | 1 | 周期数;**`dtype`**=week 时表示周数。 |
| **`country`** | query | string | 是 | "KZ" | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`services`** | query | string | 是 | "opt6,opt7,opt8" | 逗号分隔的服务代码。 [服务列表](/zh/docs/rental/reference-data) |
| **`provider`** | query | string | 否 | "T-Mobile" | 可选供应商名称;省略时,从可用供应商中随机选择。 |
| **`partner_key`** | query | string | 否 | "partnerkeyhere" | 可选的推荐合作方密钥。 |
## 使用说明 [#使用说明]
为多个服务租赁同一个号码。在 **`services`** 中传入逗号分隔的服务代码,并先检查[多服务余量](/zh/docs/rental/multi-service-count)。
先选择[国家](/zh/docs/rental/countries),按相同国家和租期比较[服务、供应商及价格](/zh/docs/rental/data-by-provider)。创建后,在[租赁订单](/zh/docs/rental/orders)中找到订单,并在发送短信前[激活](/zh/docs/rental/activate)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=create_multi" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1" \
--data-urlencode "country=KZ" \
--data-urlencode "services=opt6,opt7,opt8"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt6,opt7,opt8";
const query = new URLSearchParams({
"method": "create_multi",
"dtype": dtype,
"dcount": dcount,
"country": country,
"services": services
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt6,opt7,opt8";
const query = new URLSearchParams({
"method": "create_multi",
"dtype": dtype,
"dcount": dcount,
"country": country,
"services": services
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
services = os.environ.get("SMSPVA_RENTAL_SERVICES", "opt6,opt7,opt8")
query = {
"method": "create_multi",
"dtype": dtype,
"dcount": dcount,
"country": country,
"services": services
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'create_multi',
'dtype' => $dtype,
'dcount' => $dcount,
'country' => $country,
'services' => $services
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
services := env("SMSPVA_RENTAL_SERVICES", "opt6,opt7,opt8")
query := url.Values{}
query.Set("method", "create_multi")
query.Set("dtype", dtype)
query.Set("dcount", dcount)
query.Set("country", country)
query.Set("services", services)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var services = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICES") ?? "opt6,opt7,opt8";
var query = new Dictionary {
["method"] = "create_multi",
["dtype"] = dtype,
["dcount"] = dcount,
["country"] = country,
["services"] = services
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String services = env("SMSPVA_RENTAL_SERVICES", "opt6,opt7,opt8");
Map query = new LinkedHashMap<>();
query.put("method", "create_multi");
query.put("dtype", dtype);
query.put("dcount", dcount);
query.put("country", country);
query.put("services", services);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"id": 40370,
"pnumber": "9096037108",
"ccode": "+7",
"service": "opt6",
"until": "1587633960"
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | |
| **`data.id`** | integer | 订单 ID |
| **`data.pnumber`** | string | 不含国家区号的电话号码 |
| **`data.ccode`** | string | 数字国家代码 |
| **`data.service`** | string | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`data.until`** | string | 到期时间(Unix 时间戳) |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 创建租赁 (/zh/docs/rental/create)
GET{"https://smspva.com/api/rent.php?method=create"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "create" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`dtype`** | query | string | 是 | "week" | 周期单位:week 或 month |
| **`dcount`** | query | integer | 是 | 1 | 周期数;**`dtype`**=week 时表示周数。 |
| **`country`** | query | string | 是 | "KZ" | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`service`** | query | string | 是 | "opt6" | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`provider`** | query | string | 否 | "T-Mobile" | 可选供应商名称;省略时,从可用供应商中随机选择。 |
| **`partner_key`** | query | string | 否 | "partnerkeyhere" | 可选的推荐合作方密钥。 |
## 使用说明 [#使用说明]
为一个服务租赁号码。同一号码需要多个服务时,请先查询[余量](/zh/docs/rental/multi-service-count),再[创建多服务租赁](/zh/docs/rental/create-multi)。
先选择[国家](/zh/docs/rental/countries),按相同国家和租期比较[服务、供应商及价格](/zh/docs/rental/data-by-provider)。创建后,在[租赁订单](/zh/docs/rental/orders)中找到订单,并在发送短信前[激活](/zh/docs/rental/activate)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=create" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1" \
--data-urlencode "country=KZ" \
--data-urlencode "service=opt6"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt6";
const query = new URLSearchParams({
"method": "create",
"dtype": dtype,
"dcount": dcount,
"country": country,
"service": service
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt6";
const query = new URLSearchParams({
"method": "create",
"dtype": dtype,
"dcount": dcount,
"country": country,
"service": service
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
service = os.environ.get("SMSPVA_RENTAL_SERVICE", "opt6")
query = {
"method": "create",
"dtype": dtype,
"dcount": dcount,
"country": country,
"service": service
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'create',
'dtype' => $dtype,
'dcount' => $dcount,
'country' => $country,
'service' => $service
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
service := env("SMSPVA_RENTAL_SERVICE", "opt6")
query := url.Values{}
query.Set("method", "create")
query.Set("dtype", dtype)
query.Set("dcount", dcount)
query.Set("country", country)
query.Set("service", service)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var service = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICE") ?? "opt6";
var query = new Dictionary {
["method"] = "create",
["dtype"] = dtype,
["dcount"] = dcount,
["country"] = country,
["service"] = service
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String service = env("SMSPVA_RENTAL_SERVICE", "opt6");
Map query = new LinkedHashMap<>();
query.put("method", "create");
query.put("dtype", dtype);
query.put("dcount", dcount);
query.put("country", country);
query.put("service", service);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"id": 40370,
"pnumber": "9096037108",
"ccode": "+7",
"service": "opt6",
"until": "1587633960"
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | |
| **`data.id`** | integer | 订单 ID |
| **`data.pnumber`** | string | 不含国家区号的电话号码 |
| **`data.ccode`** | string | 数字国家代码 |
| **`data.service`** | string | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`data.until`** | string | 到期时间(Unix 时间戳) |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 按供应商查询租赁数据 (/zh/docs/rental/data-by-provider)
GET{"https://smspva.com/api/rent.php?method=getdataWithProviders"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
**apikey** 查询参数可选。公共数据可省略;按文档传入后可获取账户相关数据或价格。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "getdataWithProviders" | 方法名称 |
| **`apikey`** | query | string | 否 | (optional) | 可选 API 密钥,传入后可能影响账户相关租赁数据及价格。 |
| **`country`** | query | string | 是 | "KZ" | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`dtype`** | query | string | 否 | "week" | 周期单位:week 或 month,省略时为 week。 |
| **`dcount`** | query | integer | 否 | 1 | 周期数;**`dtype`**=week 时表示周数,省略时为 1。 |
| **`extend`** | query | string | 否 | "1" | 启用扩展响应格式的可选标记。 |
## 使用说明 [#使用说明]
比较指定 **`country`** 的可用服务、日价及供应商余量。**`dtype`** 和 **`dcount`** 应与实际租期一致。
国家代码见[租赁国家](/zh/docs/rental/countries)。选好服务后,用其代码[创建租赁](/zh/docs/rental/create)或[创建多服务租赁](/zh/docs/rental/create-multi)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
# Optional: add --data-urlencode "apikey=$SMSPVA_API_KEY" for account-specific data.
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getdataWithProviders" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdataWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdataWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ.get("SMSPVA_API_KEY")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getdataWithProviders",
"country": country,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getdataWithProviders',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := os.Getenv("SMSPVA_API_KEY")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getdataWithProviders")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getdataWithProviders",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", "");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getdataWithProviders");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"services": [
{
"name": "1cupis & okcupid & winline",
"service": "opt48",
"price_day": 5,
"img": "images/ico/cupis_okcupid_winline.ico",
"procent_days": 0,
"procent": 0,
"day_step": 0,
"count": {
"Claro_AR": 27
},
"totalCount": 12
}
],
"totalAmount": 1735,
"allOperators": [
"Claro_AR"
]
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | |
| **`data.services`** | array<object> | |
| **`data.services[].name`** | string | 服务名称 |
| **`data.services[].service`** | string | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`data.services[].price_day`** | number | 该服务的日价 |
| **`data.services[].img`** | string | 服务图标 URL |
| **`data.services[].procent_days`** | integer | 适用折扣的天数 |
| **`data.services[].procent`** | integer | 折扣百分比 |
| **`data.services[].day_step`** | integer | 计价天数步长 |
| **`data.services[].count`** | object | 该服务在各运营商的可用号码数量 |
| **`data.services[].count.*`** | integer | |
| **`data.services[].totalCount`** | integer | 该服务的可用号码总数 |
| **`data.totalAmount`** | integer | 全部服务的可用号码总数 |
| **`data.allOperators`** | array<string> | 该国家全部可用运营商 |
| **`msg`** | string | status 为 0 时的错误原因,此时 HTTP 仍可能为 200。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 租赁数据 (/zh/docs/rental/data)
GET{"https://smspva.com/api/rent.php?method=getdata"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
**apikey** 查询参数可选。公共数据可省略;按文档传入后可获取账户相关数据或价格。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "getdata" | 方法名称 |
| **`apikey`** | query | string | 否 | (optional) | 可选 API 密钥,传入后可能影响账户相关租赁数据。 |
| **`country`** | query | string | 是 | "KZ" | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`dtype`** | query | string | 否 | "week" | 周期单位:week 或 month,省略时为 week。 |
| **`dcount`** | query | integer | 否 | 1 | 周期数;**`dtype`**=week 时表示周数,省略时为 1。 |
| **`extend`** | query | string | 否 | "1" | 设为 1 时,每个服务条目额外返回 **`procent_days`**、procent 和 **`day_step`** 价格设置。 |
## 使用说明 [#使用说明]
查询所选 **`country`** 和租期的服务价格及号码余量。**`dtype`** 使用 **`week`** 或 **`month`**,**`dcount`** 为周期数。
服务条目包含名称、代码、日价、数量和图标路径,**`data.totalAmount`** 为总量。传入 **`extend=1`** 可额外获取 **`procent_days`**、**`procent`** 和 **`day_step`** 价格设置。即使 HTTP 为 **200**,也要检查 **`status`**:**0** 表示失败,原因见 **`msg`**。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
# Optional: add --data-urlencode "apikey=$SMSPVA_API_KEY" for account-specific data.
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=getdata" \
--data-urlencode "country=KZ" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdata",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const apiKey = process.env.SMSPVA_API_KEY;
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "getdata",
"country": country,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ.get("SMSPVA_API_KEY")
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "getdata",
"country": country,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'getdata',
'country' => $country,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := os.Getenv("SMSPVA_API_KEY")
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "getdata")
query.Set("country", country)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("SMSPVA_API_KEY");
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "getdata",
["country"] = country,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", "");
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "getdata");
query.put("country", country);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"services": [
{
"name": "Airbnb",
"service": "opt46",
"price_day": 6,
"count": 359,
"img": "images/ico/whatsapp.png",
"procent_days": 0,
"procent": 0,
"day_step": 0
}
],
"totalAmount": 100
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | |
| **`data.services`** | array<object> | |
| **`data.services[].name`** | string | 服务名称 |
| **`data.services[].service`** | string | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`data.services[].price_day`** | number | 日价 |
| **`data.services[].count`** | integer | 可用数量 |
| **`data.services[].img`** | string | 服务图标路径。 |
| **`data.services[].procent_days`** | integer | 适用折扣的天数,**`extend=1`** 时返回。 |
| **`data.services[].procent`** | integer | 折扣百分比,**`extend=1`** 时返回。 |
| **`data.services[].day_step`** | number | 计价天数步长,**`extend=1`** 时返回。 |
| **`data.totalAmount`** | integer | 全部服务的可用号码总数 |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 默认服务 (/zh/docs/rental/default-services)
GET{"https://smspva.com/api/rent.php?method=get_default_services"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
调用此方法无需 API 密钥。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "get_default_services" | 方法名称 |
## 使用说明 [#使用说明]
获取租赁 API 的默认服务列表。查询具体国家的价格和余量,请使用[租赁数据](/zh/docs/rental/data)或[供应商数据](/zh/docs/rental/data-by-provider)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_default_services"
```
```js
const query = new URLSearchParams({
"method": "get_default_services"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const query = new URLSearchParams({
"method": "get_default_services"
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
query = {
"method": "get_default_services"
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_default_services'
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
query := url.Values{}
query.Set("method", "get_default_services")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var query = new Dictionary {
["method"] = "get_default_services"
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
Map query = new LinkedHashMap<>();
query.put("method", "get_default_services");
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": [
{
"name": "WhatsApp",
"service": "opt20",
"priceForDay": "0.20",
"img": "images/ico/whatsapp.png",
"DAYP": "30",
"PROC": "30"
}
]
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | array<object> | |
| **`data[].name`** | string | 服务名称. |
| **`data[].service`** | string | 服务代码。 |
| **`data[].priceForDay`** | string | 租赁日价,以字符串返回。 |
| **`data[].img`** | string | 服务图标路径。 |
| **`data[].DAYP`** | string | 服务器返回的租赁价格设置。 |
| **`data[].PROC`** | string | 服务器返回的租赁价格设置。 |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 移除订单 (/zh/docs/rental/delete)
GET{"https://smspva.com/api/rent.php?method=delete"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "delete" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`id`** | query | integer | 是 | "" | 订单 ID |
## 使用说明 [#使用说明]
移除租赁订单。使用 **GET**,传入 **`method=delete`** 及本方法要求的订单 ID。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=delete" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "delete",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "delete",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "delete",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'delete',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "delete")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "delete",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "delete");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"id": 123
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | |
| **`data.id`** | integer | 订单 ID |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 租赁错误与响应 (/zh/docs/rental/errors)
## HTTP 200 不保证成功 [#http-200-不保证成功]
接口文档定义 HTTP **200**,但 **status=0** 仍表示失败,**status=1** 表示成功。存在时读取 **msg**,不要要求 Activation V2 的 **`statusCode`** 或 **`error.type`**。
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
这是 **`restore_user`** 可能返回的错误。接口页面列出了成功和错误响应,请先判断结果,再读取恢复后的订单 ID。
## 等待及空列表 [#等待及空列表]
**SmsList** 和 **OtherSms** 可在 **`status=1`** 时为空。不要套用 Activation V2 的 202 等待逻辑。通过[订单](/zh/docs/rental/orders)检查激活状态及过期时间。
## 网络与空响应 [#网络与空响应]
超时、空响应体或非 JSON 不能确认成功。原文档说明,get_min_paypal_days 在缺少 country 或 service 时可能返回空 HTTP 响应,应提供所有必填参数。
购买、延期或恢复的结果不明时,先查看订单和历史再决定是否重试:即使没有收到响应,操作也可能已经完成。
## 原始错误信息 [#原始错误信息]
恢复示例包括 **Incorrect order id**、**Order not found**、**NOBALANCE_12.50** 和 **The number is busy, there is already an order for this service**。这些是可能收到的信息示例,其他接口也可能返回不同内容。具体请看[接口参考](/zh/docs/rental)。
# 租赁代码示例 (/zh/docs/rental/examples)
[22 个租赁方法](/zh/docs/rental)均提供 cURL、JavaScript、TypeScript、Python、PHP、Go、C# 和 Java。所有请求使用 GET,并将参数编码到 **https://smspva.com/api/rent.php**。
## 环境 [#环境]
cURL 7.76+ 和 POSIX shell;JavaScript 使用 Node.js 22.16+;TypeScript 使用带 Node 类型的 ESM 项目;Python 3.10+;PHP 8.1+ 及 curl 扩展;Go 1.20+;.NET 8+ 控制台;Java 11+ 及 Jackson Databind。
JavaScript 保存为 Example.mjs,TypeScript 为 Example.mts,Python 为 Example.py,PHP 为 Example.php;C# 放入 Program.cs。Java 在 Maven 项目中加入 Jackson,运行时将依赖放入 classpath,或通过 IDE 执行:
```xml
com.fasterxml.jackson.core
jackson-databind
2.22.4
```
来源:[Maven Central](https://central.sonatype.com/artifact/com.fasterxml.jackson.core/jackson-databind)。Jackson 用于在 HTTP 200 时仍检查 JSON status。
## 环境变量 [#环境变量]
```text
# macOS / Linux / WSL
export SMSPVA_API_KEY="YOUR_API_KEY"
```
```text
# PowerShell
$env:SMSPVA_API_KEY = "YOUR_API_KEY"
$env:SMSPVA_RENTAL_ORDER_ID = "123"
$env:SMSPVA_RENTAL_NUMBER = "79335445295"
```
请将订单和号码替换为实际租赁值。公共方法无需密钥;可选密钥方法在环境未设置时省略。密钥通过 **apikey 查询参数**传递,不使用请求头。账户请求应在服务器执行,并在访问日志中隐藏 **`apikey`**。
其他参数采用原文档示例值,可修改代码或使用完整前缀 **`SMSPVA_RENTAL_`** 加 COUNTRY、SERVICE、SERVICES、DTYPE、DCOUNT、SKIP、TAKE、RENT_DAYS,仅在支持的接口中设置。cURL 中直接修改字面值。
## 可选参数及响应 [#可选参数及响应]
最小示例省略 provider、**`partner_key`**、extend;只在文档支持的方法中添加。**partner_key** 是 Rental 查询参数,不同于 Activation V2 的 **`partnerkey`** 请求头。
示例设置 30 秒超时,对查询值编码且不自动重试。cURL 输出响应体,使用 data 前请自行检查 **status**;其余语言同时检查 HTTP 和 **status=1**。
# 租赁历史 (/zh/docs/rental/history)
GET{"https://smspva.com/api/rent.php?method=get_rent_history"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "get_rent_history" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`skip`** | query | integer | 否 | 0 | 跳过的条目数 |
| **`take`** | query | integer | 否 | 10 | 返回条目数 |
## 使用说明 [#使用说明]
查看已结束的租赁,用 **`isAvailForRestore`** 判断能否恢复。符合条件时,请先查询[费用和时长](/zh/docs/rental/restore-precalculation),再[恢复租赁](/zh/docs/rental/restore)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_rent_history" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "skip=0" \
--data-urlencode "take=10"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const skip = process.env.SMSPVA_RENTAL_SKIP ?? "0";
const take = process.env.SMSPVA_RENTAL_TAKE ?? "10";
const query = new URLSearchParams({
"method": "get_rent_history",
"skip": skip,
"take": take
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const skip = process.env.SMSPVA_RENTAL_SKIP ?? "0";
const take = process.env.SMSPVA_RENTAL_TAKE ?? "10";
const query = new URLSearchParams({
"method": "get_rent_history",
"skip": skip,
"take": take
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
skip = os.environ.get("SMSPVA_RENTAL_SKIP", "0")
take = os.environ.get("SMSPVA_RENTAL_TAKE", "10")
query = {
"method": "get_rent_history",
"skip": skip,
"take": take
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_rent_history',
'skip' => $skip,
'take' => $take
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
skip := env("SMSPVA_RENTAL_SKIP", "0")
take := env("SMSPVA_RENTAL_TAKE", "10")
query := url.Values{}
query.Set("method", "get_rent_history")
query.Set("skip", skip)
query.Set("take", take)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var skip = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SKIP") ?? "0";
var take = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_TAKE") ?? "10";
var query = new Dictionary {
["method"] = "get_rent_history",
["skip"] = skip,
["take"] = take
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String skip = env("SMSPVA_RENTAL_SKIP", "0");
String take = env("SMSPVA_RENTAL_TAKE", "10");
Map query = new LinkedHashMap<>();
query.put("method", "get_rent_history");
query.put("skip", skip);
query.put("take", take);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": [
{
"orderId": 857191,
"resourceCode": "opt9",
"number": "37067787324",
"branchId": 684,
"haveSms": false,
"isAvailForRestore": true,
"days": 30,
"country": "LT",
"begin": 1768902473,
"end": 1771494473,
"closed": 1768903921
}
]
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | array<object> | |
| **`data[].orderId`** | integer | 订单 ID |
| **`data[].resourceCode`** | string | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`data[].number`** | string | 租赁号码,含国家区号,不带 +。 |
| **`data[].branchId`** | integer | 订单内部业务分支 ID |
| **`data[].haveSms`** | boolean | 租赁期间该号码是否收到过短信。 |
| **`data[].isAvailForRestore`** | boolean | 是否可以恢复;为 true 时,可用 Restore 以新号码恢复租赁。 |
| **`data[].days`** | integer | 订单原租赁天数 |
| **`data[].country`** | string | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`data[].begin`** | integer | 开始时间(Unix 时间戳) |
| **`data[].end`** | integer | 结束时间(Unix 时间戳) |
| **`data[].closed`** | integer | 关闭时间(Unix 时间戳) |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# Rental API (/zh/docs/rental)
地址:**https://smspva.com/api/rent.php**。所有接口通过 **GET** 和查询参数 **method** 选择方法。密钥使用 **apikey 查询参数**,不同于 Activation V2 的请求头。使用 data 前检查 **status=1**;HTTP 200 下的 **status=0** 仍为应用失败。
创建、激活、读取短信、延期及恢复。
来自原有数据源的实时租赁列表。
## 基础数据 [#基础数据]
| method | 说明 |
| --- | --- |
| **`getcountries`** | [租赁国家](/zh/docs/rental/countries) |
| **`get_default_services`** | [默认服务](/zh/docs/rental/default-services) |
| **`get_country_by_service`** | [按服务查询国家](/zh/docs/rental/countries-by-service) |
## 价格与余量 [#价格与余量]
| method | 说明 |
| --- | --- |
| **`getdata`** | [租赁数据](/zh/docs/rental/data) |
| **`getdataWithProviders`** | [按供应商查询租赁数据](/zh/docs/rental/data-by-provider) |
| **`getcount`** | [可用号码数量](/zh/docs/rental/count) |
| **`getCountWithProviders`** | [按供应商查询余量](/zh/docs/rental/counts-by-provider) |
| **`get_count_multi`** | [多服务余量](/zh/docs/rental/multi-service-count) |
| **`get_days_canada_paypal`** | [加拿大 PayPal 天数](/zh/docs/rental/canada-paypal-days) |
| **`get_min_paypal_days`** | [PayPal 最短天数](/zh/docs/rental/minimum-paypal-days) |
## 订单与短信 [#订单与短信]
| method | 说明 |
| --- | --- |
| **`create`** | [创建租赁](/zh/docs/rental/create) |
| **`create_multi`** | [创建多服务租赁](/zh/docs/rental/create-multi) |
| **`add_service_to_order`** | [向订单添加服务](/zh/docs/rental/add-service) |
| **`orders`** | [租赁订单](/zh/docs/rental/orders) |
| **`activate`** | [激活租赁](/zh/docs/rental/activate) |
| **`sms`** | [租赁短信](/zh/docs/rental/sms) |
## 管理租赁 [#管理租赁]
| method | 说明 |
| --- | --- |
| **`prolong`** | [延长租赁](/zh/docs/rental/prolong) |
| **`prolong_max`** | [按天延长](/zh/docs/rental/prolong-max) |
| **`delete`** | [移除订单](/zh/docs/rental/delete) |
## 历史与恢复 [#历史与恢复]
| method | 说明 |
| --- | --- |
| **`get_rent_history`** | [租赁历史](/zh/docs/rental/history) |
| **`restore_user_precalc`** | [恢复预估](/zh/docs/rental/restore-precalculation) |
| **`restore_user`** | [恢复租赁](/zh/docs/rental/restore) |
# PayPal 最短天数 (/zh/docs/rental/minimum-paypal-days)
GET{"https://smspva.com/api/rent.php?method=get_min_paypal_days"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
调用此方法无需 API 密钥。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "get_min_paypal_days" | 方法名称 |
| **`country`** | query | string | 是 | "CA" | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`service`** | query | string | 是 | "opt83" | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
## 使用说明 [#使用说明]
按 **`country`** 和 **`service`** 查询 PayPal 最短租期。两项都要传入,缺少任意一项时,后端可能返回空 HTTP 响应。国家代码见[租赁国家](/zh/docs/rental/countries),加拿大还可查询[PayPal 天数](/zh/docs/rental/canada-paypal-days)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_min_paypal_days" \
--data-urlencode "country=CA" \
--data-urlencode "service=opt83"
```
```js
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "CA";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt83";
const query = new URLSearchParams({
"method": "get_min_paypal_days",
"country": country,
"service": service
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "CA";
const service = process.env.SMSPVA_RENTAL_SERVICE ?? "opt83";
const query = new URLSearchParams({
"method": "get_min_paypal_days",
"country": country,
"service": service
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "CA")
service = os.environ.get("SMSPVA_RENTAL_SERVICE", "opt83")
query = {
"method": "get_min_paypal_days",
"country": country,
"service": service
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_min_paypal_days',
'country' => $country,
'service' => $service
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
country := env("SMSPVA_RENTAL_COUNTRY", "CA")
service := env("SMSPVA_RENTAL_SERVICE", "opt83")
query := url.Values{}
query.Set("method", "get_min_paypal_days")
query.Set("country", country)
query.Set("service", service)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "CA";
var service = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICE") ?? "opt83";
var query = new Dictionary {
["method"] = "get_min_paypal_days",
["country"] = country,
["service"] = service
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String country = env("SMSPVA_RENTAL_COUNTRY", "CA");
String service = env("SMSPVA_RENTAL_SERVICE", "opt83");
Map query = new LinkedHashMap<>();
query.put("method", "get_min_paypal_days");
query.put("country", country);
query.put("service", service);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"Days": 30,
"Status": 1,
"Message": ""
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | 最短租期及其可用情况。 |
| **`data.Days`** | integer | 最短租赁天数。 |
| **`data.Status`** | integer | 服务器返回的可用状态,与顶层 status 不同。 |
| **`data.Message`** | string | 服务器返回的可用情况说明。 |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 多服务余量 (/zh/docs/rental/multi-service-count)
GET{"https://smspva.com/api/rent.php?method=get_count_multi"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
调用此方法无需 API 密钥。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "get_count_multi" | 方法名称 |
| **`country`** | query | string | 是 | "KZ" | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`services`** | query | string | 是 | "opt1,opt2" | 逗号分隔的服务代码。 [服务列表](/zh/docs/rental/reference-data) |
| **`dtype`** | query | string | 否 | "week" | 周期单位:week 或 month |
| **`dcount`** | query | integer | 否 | 1 | 周期数;**`dtype`**=week 时表示周数。 |
## 使用说明 [#使用说明]
查询同时支持所选服务组合的号码数量,在 **`services`** 中传入代码。此方法请始终明确传入 **`dtype`** 和 **`dcount`**,其后端默认值暂不可靠。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=get_count_multi" \
--data-urlencode "country=KZ" \
--data-urlencode "services=opt1,opt2" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt1,opt2";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "get_count_multi",
"country": country,
"services": services,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
const country = process.env.SMSPVA_RENTAL_COUNTRY ?? "KZ";
const services = process.env.SMSPVA_RENTAL_SERVICES ?? "opt1,opt2";
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "get_count_multi",
"country": country,
"services": services,
"dtype": dtype,
"dcount": dcount
});
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
country = os.environ.get("SMSPVA_RENTAL_COUNTRY", "KZ")
services = os.environ.get("SMSPVA_RENTAL_SERVICES", "opt1,opt2")
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "get_count_multi",
"country": country,
"services": services,
"dtype": dtype,
"dcount": dcount
}
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'get_count_multi',
'country' => $country,
'services' => $services,
'dtype' => $dtype,
'dcount' => $dcount
];
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
country := env("SMSPVA_RENTAL_COUNTRY", "KZ")
services := env("SMSPVA_RENTAL_SERVICES", "opt1,opt2")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "get_count_multi")
query.Set("country", country)
query.Set("services", services)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
var country = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_COUNTRY") ?? "KZ";
var services = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_SERVICES") ?? "opt1,opt2";
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "get_count_multi",
["country"] = country,
["services"] = services,
["dtype"] = dtype,
["dcount"] = dcount
};
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String country = env("SMSPVA_RENTAL_COUNTRY", "KZ");
String services = env("SMSPVA_RENTAL_SERVICES", "opt1,opt2");
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "get_count_multi");
query.put("country", country);
query.put("services", services);
query.put("dtype", dtype);
query.put("dcount", dcount);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"count": 10
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | |
| **`data.count`** | integer | |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 租赁订单 (/zh/docs/rental/orders)
GET{"https://smspva.com/api/rent.php?method=orders"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "orders" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
## 使用说明 [#使用说明]
查看有效租赁、当前状态及延期选项。用订单 ID [激活](/zh/docs/rental/activate)、[读取短信](/zh/docs/rental/sms)或[延期](/zh/docs/rental/prolong)。已结束的租赁及恢复资格见[租赁历史](/zh/docs/rental/history)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=orders" \
--data-urlencode "apikey=$SMSPVA_API_KEY"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const query = new URLSearchParams({
"method": "orders"
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
query = {
"method": "orders"
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'orders'
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
query := url.Values{}
query.Set("method", "orders")
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var query = new Dictionary {
["method"] = "orders"
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
Map query = new LinkedHashMap<>();
query.put("method", "orders");
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": [
{
"id": 40300,
"scode": "opt16",
"sname": "Instagram",
"state": 0,
"pnumber": "9096068511",
"ccode": "+7",
"cname": "KZ",
"hasnewsms": false,
"until": 1587552240,
"canprolong": true,
"canprolongmax": 162,
"canprolonguntil": 1634883780,
"lastonline": 1586947920
}
]
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | array<object> | |
| **`data[].id`** | integer | 订单 ID |
| **`data[].scode`** | string | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`data[].sname`** | string | 服务名称 |
| **`data[].state`** | integer | 订单状态:0 未激活,1 已激活,2 激活中,-1 系统中不存在。 |
| **`data[].pnumber`** | string | 不含国家区号的电话号码 |
| **`data[].ccode`** | string | 数字国家代码 |
| **`data[].cname`** | string | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`data[].hasnewsms`** | boolean | 此订单收到新短信。 |
| **`data[].until`** | integer | 到期时间(Unix 时间戳) |
| **`data[].canprolong`** | boolean | 该订单是否可延期。 |
| **`data[].canprolongmax`** | integer | 最多可延期的天数,不可超过此限制。 |
| **`data[].canprolonguntil`** | integer | 可办理延期的截止时间,Unix 时间戳,超过后无法延期。 |
| **`data[].lastonline`** | integer | 号码最近在线时间(Unix 时间戳) |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 按天延长 (/zh/docs/rental/prolong-max)
GET{"https://smspva.com/api/rent.php?method=prolong_max"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "prolong_max" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`id`** | query | integer | 是 | 123 | 订单 ID |
| **`dtype`** | query | string | 是 | "day" | 时长单位,必须为 "day"。 |
| **`dcount`** | query | integer | 是 | 5 | 延期天数(1-6),同时不能超过该订单的 **`canprolongmax`**。 |
## 使用说明 [#使用说明]
用 **`dtype=day`** 按天延期,**`dcount`** 为 **1–6**。请先在[租赁订单](/zh/docs/rental/orders)中查看 **`canprolong`**、**`canprolongmax`** 和 **`canprolonguntil`**,延期不能超出该订单的限制。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=prolong_max" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID" \
--data-urlencode "dtype=day" \
--data-urlencode "dcount=5"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "day";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "5";
const query = new URLSearchParams({
"method": "prolong_max",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "day";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "5";
const query = new URLSearchParams({
"method": "prolong_max",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "day")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "5")
query = {
"method": "prolong_max",
"id": id,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'prolong_max',
'id' => $id,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "day")
dcount := env("SMSPVA_RENTAL_DCOUNT", "5")
query := url.Values{}
query.Set("method", "prolong_max")
query.Set("id", id)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "day";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "5";
var query = new Dictionary {
["method"] = "prolong_max",
["id"] = id,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "day");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "5");
Map query = new LinkedHashMap<>();
query.put("method", "prolong_max");
query.put("id", id);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
按天延期的结果。
**application/json**
**成功延期,最多 7 天**
```json
{
"status": 1
}
```
**Incorrect order id**
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
**Order not found**
```json
{
"status": 0,
"msg": "Order not found"
}
```
**Invalid duration parameters**
```json
{
"status": 0,
"msg": "More than 7 days or type is not day"
}
```
**Insufficient funds in account**
```json
{
"status": 0,
"msg": "Insufficient balance"
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 延长租赁 (/zh/docs/rental/prolong)
GET{"https://smspva.com/api/rent.php?method=prolong"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "prolong" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`id`** | query | integer | 是 | 123 | 订单 ID |
| **`dtype`** | query | string | 是 | "week" | 周期单位:week 或 month |
| **`dcount`** | query | integer | 是 | 1 | 周期数;**`dtype`**=week 时表示周数。 |
## 使用说明 [#使用说明]
按所需周数或月数延长租赁。请先在[租赁订单](/zh/docs/rental/orders)中查看 **`canprolong`**、**`canprolongmax`** 和 **`canprolonguntil`**,延期不能超出该订单的限制。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=prolong" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID" \
--data-urlencode "dtype=week" \
--data-urlencode "dcount=1"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "prolong",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const dtype = process.env.SMSPVA_RENTAL_DTYPE ?? "week";
const dcount = process.env.SMSPVA_RENTAL_DCOUNT ?? "1";
const query = new URLSearchParams({
"method": "prolong",
"id": id,
"dtype": dtype,
"dcount": dcount
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
dtype = os.environ.get("SMSPVA_RENTAL_DTYPE", "week")
dcount = os.environ.get("SMSPVA_RENTAL_DCOUNT", "1")
query = {
"method": "prolong",
"id": id,
"dtype": dtype,
"dcount": dcount
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'prolong',
'id' => $id,
'dtype' => $dtype,
'dcount' => $dcount
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
dtype := env("SMSPVA_RENTAL_DTYPE", "week")
dcount := env("SMSPVA_RENTAL_DCOUNT", "1")
query := url.Values{}
query.Set("method", "prolong")
query.Set("id", id)
query.Set("dtype", dtype)
query.Set("dcount", dcount)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var dtype = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DTYPE") ?? "week";
var dcount = Environment.GetEnvironmentVariable("SMSPVA_RENTAL_DCOUNT") ?? "1";
var query = new Dictionary {
["method"] = "prolong",
["id"] = id,
["dtype"] = dtype,
["dcount"] = dcount
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
String dtype = env("SMSPVA_RENTAL_DTYPE", "week");
String dcount = env("SMSPVA_RENTAL_DCOUNT", "1");
Map query = new LinkedHashMap<>();
query.put("method", "prolong");
query.put("id", id);
query.put("dtype", dtype);
query.put("dcount", dcount);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
订单延期结果。
**application/json**
**延期成功**
```json
{
"status": 1
}
```
**Incorrect order id**
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
**Order not found**
```json
{
"status": 0,
"msg": "Order not found"
}
```
**Incorrect duration type**
```json
{
"status": 0,
"msg": "Incorrect duration type. Available types: week, month"
}
```
**Incorrect duration count**
```json
{
"status": 0,
"msg": "Incorrect duration count. Min 7 days. Max 90 days."
}
```
**Insufficient funds in account**
```json
{
"status": 0,
"msg": "Insufficient balance"
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 国家与服务 (/zh/docs/rental/reference-data)
在这里选择号码租赁的国家和服务代码。创建订单前,请比较价格、供应商、租期和余量。这些代码及可用服务可能与 Activation V2 不同。
打开页面时加载列表,页面可见时每**五分钟**刷新。数据源也有五分钟缓存,新变更可能稍后才显示。
[实时 JSON](/reference-data.php) · [按供应商查询](/zh/docs/rental/data-by-provider)
# 恢复预估 (/zh/docs/rental/restore-precalculation)
GET{"https://smspva.com/api/rent.php?method=restore_user_precalc"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "restore_user_precalc" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`id`** | query | integer | 是 | "" | 订单 ID |
## 使用说明 [#使用说明]
查询过期租赁的恢复费用、时长及可用情况。订单 ID 取自[租赁历史](/zh/docs/rental/history),且 **`isAvailForRestore`** 必须为 **true**。这一步仅作预估,实际恢复需调用[恢复租赁](/zh/docs/rental/restore)。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=restore_user_precalc" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user_precalc",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user_precalc",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "restore_user_precalc",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'restore_user_precalc',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "restore_user_precalc")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "restore_user_precalc",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "restore_user_precalc");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"ccode": "LT",
"scode": "opt9",
"price": 1.5,
"sname": "Instagram",
"pnumber": "37067787324",
"outdays": 5,
"orderid": 857191,
"prolongTo": 30
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | |
| **`data.ccode`** | string | 号码所属国家代码。 [国家列表](/zh/docs/rental/reference-data) |
| **`data.scode`** | string | 服务代码 [服务列表](/zh/docs/rental/reference-data) |
| **`data.price`** | number | 恢复该订单的费用 |
| **`data.sname`** | string | 服务名称 |
| **`data.pnumber`** | string | 租赁号码,含国家区号,不带 +。 |
| **`data.outdays`** | integer | 订单过期至今的天数 |
| **`data.orderid`** | integer | 订单 ID |
| **`data.prolongTo`** | integer | 恢复后订单的有效天数 |
| **`msg`** | string | status 为 0 时的错误原因。 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 恢复租赁 (/zh/docs/rental/restore)
GET{"https://smspva.com/api/rent.php?method=restore_user"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
此请求可能修改租赁订单或产生费用。响应丢失后,先查询订单及历史,再决定是否重试:更改可能已经生效。示例不会自动重试。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "restore_user" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`id`** | query | integer | 是 | "" | 订单 ID |
## 使用说明 [#使用说明]
恢复符合条件的已结束租赁。先在[历史](/zh/docs/rental/history)获取 ID,检查 **`isAvailForRestore`**,并确认[费用与时长](/zh/docs/rental/restore-precalculation)。
成功时 **`status=1`**,**`data.id`** 为恢复后的**新订单 ID**。用它查询[租赁订单](/zh/docs/rental/orders)。若 **`status=0`**,原因见 **`msg`**。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=restore_user" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "restore_user",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "restore_user",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'restore_user',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "restore_user")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "restore_user",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "restore_user");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
成功时返回恢复后的订单 ID,失败时返回错误信息。
**application/json**
**恢复成功**
```json
{
"status": 1,
"data": {
"id": 123456
}
}
```
**Incorrect order ID**
```json
{
"status": 0,
"msg": "Incorrect order id"
}
```
**Order not found**
```json
{
"status": 0,
"msg": "Order not found"
}
```
**Not enough balance**
```json
{
"status": 0,
"msg": "NOBALANCE_12.50"
}
```
**Number is busy**
```json
{
"status": 0,
"msg": "The number is busy, there is already an order for this service"
}
```
**成功**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 请求状态。**`1`** 表示订单恢复成功。 |
| **`data`** | object | 恢复后的订单数据。 |
| **`data.id`** | integer | 恢复后的新订单 ID。 |
必填: **`status`**, **`data`**
**错误**
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 请求状态。**`0`** 表示恢复失败。 |
| **`msg`** | string | 错误信息。 |
必填: **`status`**, **`msg`**
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 租赁短信 (/zh/docs/rental/sms)
GET{"https://smspva.com/api/rent.php?method=sms"}
发送 **GET** 请求后,检查 JSON 中的 **`status`**:**1** 成功,**0** 失败,即使 HTTP 为 **200** 也一样。失败原因见 **`msg`**。
## 身份验证 [#身份验证]
**apikey** 为必填**查询参数**。
## 参数 [#参数]
| 名称 | 位置 | 类型 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- | --- | --- |
| **`method`** | query | string | 是 | "sms" | 方法名称 |
| **`apikey`** | query | string | 是 | **`SMSPVA_API_KEY`** | 你的 API 密钥 可在网站右上角菜单的 Profile and APIKEY 中找到。 |
| **`id`** | query | integer | 是 | 123 | 订单 ID |
## 使用说明 [#使用说明]
用[租赁订单](/zh/docs/rental/orders)中的 ID 读取消息。向号码发送短信前,请[激活订单](/zh/docs/rental/activate),并在订单列表确认状态。
## 请求示例 [#请求示例]
[运行环境及依赖](/zh/docs/rental/examples). 示例会对查询参数编码,最多等待 30 秒。使用 **`data`** 前请检查 HTTP 和 JSON **`status`**。cURL 输出原始响应供你检查,Java 使用 Jackson 读取 JSON。
- **`SMSPVA_RENTAL_ORDER_ID`**: id.
```bash
: "${SMSPVA_API_KEY:?Set SMSPVA_API_KEY}"
: "${SMSPVA_RENTAL_ORDER_ID:?Set SMSPVA_RENTAL_ORDER_ID}"
curl --get --fail-with-body --max-time 30 "https://smspva.com/api/rent.php" \
--data-urlencode "method=sms" \
--data-urlencode "apikey=$SMSPVA_API_KEY" \
--data-urlencode "id=$SMSPVA_RENTAL_ORDER_ID"
```
```js
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "sms",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result;
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```ts
export {};
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Set ${name}`);
return value;
}
const apiKey = required("SMSPVA_API_KEY");
const id = required("SMSPVA_RENTAL_ORDER_ID");
const query = new URLSearchParams({
"method": "sms",
"id": id
});
if (apiKey) query.set("apikey", apiKey);
const response = await fetch("https://smspva.com/api/rent.php" + "?" + query, {
method: "GET",
signal: AbortSignal.timeout(30_000),
});
const text = await response.text();
let result: { status?: number; msg?: string; data?: unknown };
try { result = JSON.parse(text); }
catch { throw new Error(`Non-JSON response (HTTP ${response.status})`); }
if (!response.ok || Number(result.status) !== 1) {
throw new Error(`HTTP ${response.status}: ${result.msg ?? "Rental request failed"}`);
}
console.log(result);
```
```python
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
api_key = os.environ["SMSPVA_API_KEY"]
id = os.environ["SMSPVA_RENTAL_ORDER_ID"]
query = {
"method": "sms",
"id": id
}
if api_key:
query["apikey"] = api_key
request = Request("https://smspva.com/api/rent.php" + "?" + urlencode(query), method="GET")
try:
with urlopen(request, timeout=30) as response:
status = response.status
text = response.read().decode("utf-8")
except HTTPError as error:
status = error.code
text = error.read().decode("utf-8", errors="replace")
except (URLError, TimeoutError) as error:
raise RuntimeError("Transport failure; no automatic retry") from error
try:
result = json.loads(text)
except json.JSONDecodeError as error:
raise RuntimeError(f"Non-JSON response (HTTP {status})") from error
if not 200 <= status < 300 or int(result.get("status", 0)) != 1:
raise RuntimeError(f"HTTP {status}: {result.get('msg', 'Rental request failed')}")
print(json.dumps(result, indent=2, ensure_ascii=False))
```
```php
'sms',
'id' => $id
];
if ($apiKey !== false && $apiKey !== '') $query['apikey'] = $apiKey;
$curl = curl_init("https://smspva.com/api/rent.php" . '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986));
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$text = curl_exec($curl);
if ($text === false) {
$message = curl_error($curl);
curl_close($curl);
throw new RuntimeException("Transport failure: $message");
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
$result = json_decode($text, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || (int)($result['status'] ?? 0) !== 1) {
throw new RuntimeException("HTTP $status: " . ($result['msg'] ?? 'Rental request failed'));
}
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
```
```go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func env(name, fallback string) string {
if value := os.Getenv(name); value != "" { return value }
if fallback != "" { return fallback }
panic("Set " + name)
}
func main() {
apiKey := env("SMSPVA_API_KEY", "")
id := env("SMSPVA_RENTAL_ORDER_ID", "")
query := url.Values{}
query.Set("method", "sms")
query.Set("id", id)
if apiKey != "" { query.Set("apikey", apiKey) }
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Get("https://smspva.com/api/rent.php" + "?" + query.Encode())
if err != nil { panic(err) }
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
var result struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
if err := json.Unmarshal(body, &result); err != nil { panic(err) }
if response.StatusCode < 200 || response.StatusCode >= 300 || result.Status != 1 {
panic(fmt.Sprintf("HTTP %d: %s", response.StatusCode, result.Msg))
}
fmt.Println(string(body))
}
```
```csharp
// .NET 8+ console application.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
static string Required(string name) => Environment.GetEnvironmentVariable(name) is { Length: > 0 } value
? value : throw new InvalidOperationException($"Set {name}");
var apiKey = Required("SMSPVA_API_KEY");
var id = Required("SMSPVA_RENTAL_ORDER_ID");
var query = new Dictionary {
["method"] = "sms",
["id"] = id
};
if (!string.IsNullOrEmpty(apiKey)) query["apikey"] = apiKey;
using var encoded = new FormUrlEncodedContent(query);
var url = "https://smspva.com/api/rent.php" + "?" + await encoded.ReadAsStringAsync();
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.GetAsync(url);
var text = await response.Content.ReadAsStringAsync();
using var document = JsonDocument.Parse(text);
var result = document.RootElement;
if (!response.IsSuccessStatusCode || !result.TryGetProperty("status", out var status) || status.GetInt32() != 1)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");
Console.WriteLine(text);
```
```java
// Java 11+. Save as Example.java; run with Jackson on the classpath.
// JSON parsing uses Jackson. See the Rental examples guide for its Maven dependency.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Example {
static String env(String name, String fallback) {
String value = System.getenv(name);
if (value != null && !value.isEmpty()) return value;
if (fallback != null) return fallback;
throw new IllegalStateException("Set " + name);
}
static String encode(String value) { return URLEncoder.encode(value, StandardCharsets.UTF_8); }
public static void main(String[] args) throws Exception {
String apiKey = env("SMSPVA_API_KEY", null);
String id = env("SMSPVA_RENTAL_ORDER_ID", null);
Map query = new LinkedHashMap<>();
query.put("method", "sms");
query.put("id", id);
if (!apiKey.isEmpty()) query.put("apikey", apiKey);
String encoded = query.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue())).collect(Collectors.joining("&"));
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://smspva.com/api/rent.php" + "?" + encoded))
.timeout(Duration.ofSeconds(30)).GET().build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode result = new ObjectMapper().readTree(response.body());
if (response.statusCode() < 200 || response.statusCode() >= 300 || result.path("status").asInt(0) != 1)
throw new java.io.IOException("HTTP " + response.statusCode() + ": " + result.path("msg").asText("Rental request failed"));
System.out.println(result.toPrettyString());
}
}
```
## 响应 [#响应]
请查看与你的请求对应的响应。数值和日期仅供示例;可选字段可能因结果或所选响应格式而不同。
### HTTP 200 [#http-200]
Success
**application/json**
**响应示例**
```json
{
"status": 1,
"data": {
"SmsList": [
{
"text": "Code Instagram: 671 094.",
"sender": "FACEBOOK",
"date": 1586948100
}
],
"OtherSms": []
}
}
```
| 名称 | 类型 | 说明 |
| --- | --- | --- |
| **`status`** | integer | 响应状态:1 成功,0 失败。 |
| **`data`** | object | |
| **`data.SmsList`** | array<object> | 已接收短信列表 |
| **`data.SmsList[].text`** | string | 短信文本 |
| **`data.SmsList[].sender`** | string | 短信发送方 |
| **`data.SmsList[].date`** | integer | 接收时间(Unix 时间戳) |
| **`data.OtherSms`** | array<unspecified> | 其他短信列表 |
## 相关指南 [#相关指南]
- [Rental API](/zh/docs/rental)
- [国家与服务](/zh/docs/rental/reference-data)
- [租赁流程](/zh/docs/rental/workflow)
- [错误](/zh/docs/rental/errors)
- [OpenAPI 定义](/openapi/rental.json)
# 租赁流程 (/zh/docs/rental/workflow)
## 1. 选择国家、服务及租期 [#1-选择国家服务及租期]
从[实时租赁列表](/zh/docs/rental/reference-data)及[租赁国家](/zh/docs/rental/countries)开始。使用相同国家及租期查询[供应商数据](/zh/docs/rental/data-by-provider),比较服务、价格和余量。
多服务使用逗号分隔的 **services**,并查询[多服务余量](/zh/docs/rental/multi-service-count)。按原文档建议,明确传入该方法的 **dtype** 和 **dcount**。多数租期接口使用 week/month,不要假定都支持天。
## 2. 创建一次租赁 [#2-创建一次租赁]
调用[创建租赁](/zh/docs/rental/create)或[多服务租赁](/zh/docs/rental/create-multi),保存 **data.id**、**pnumber**、**ccode**、**until**。它们是租赁数据,不是 Activation V2 订单 ID。两者按文档使用 GET,可能创建付费订单。响应丢失后先检查[订单](/zh/docs/rental/orders),不要直接重复创建。
## 3. 发短信前先激活 [#3-发短信前先激活]
调用[激活租赁](/zh/docs/rental/activate),再从订单检查 **state**:**0** 未激活、**1** 已激活、**2** 正在激活、**-1** 不在系统中。确认已激活后再发送短信。激活请求 **`status=1`** 不代替订单状态检查。
## 4. 读取消息 [#4-读取消息]
[租赁短信](/zh/docs/rental/sms)在 **status=1** 后读取 **data.SmsList** 和 **data.OtherSms**。空列表表示该列表当前无消息,不是 Activation V2 的 HTTP 202 等待响应。
重复读取可能返回已处理的短信,应在应用中维护处理状态。轮询应间隔执行,并在完成任务或租赁过期时停止;不要自行定义统一数值限流。接口示例仅请求一次,不自动重试。
## 5. 修改与延期 [#5-修改与延期]
- [添加服务](/zh/docs/rental/add-service):需要 id、**`pnumber`** 和 service;**`rent_days`** 可选。
- [延长租赁](/zh/docs/rental/prolong):使用 week/month,先检查 **`canprolong`**、**`canprolongmax`**、**`canprolonguntil`**。
- [按天延长](/zh/docs/rental/prolong-max):**dtype=day**、**dcount=1–6**,且不能超出 **`canprolongmax`**。
- [移除订单](/zh/docs/rental/delete):使用 GET 加 **method=delete**,不是 HTTP DELETE。
示例不会自动执行这些管理操作。
## 6. 恢复已完成租赁 [#6-恢复已完成租赁]
查看[历史](/zh/docs/rental/history)及 **isAvailForRestore**。先调用[恢复预估](/zh/docs/rental/restore-precalculation),检查价格、时长后再[恢复租赁](/zh/docs/rental/restore)。成功的 **data.id** 是新的恢复订单 ID。HTTP 200 下的 **status=0** 与 **msg** 仍表示失败。
## 时间字段 [#时间字段]
创建响应的 **until** 定义为字符串,订单列表定义为整数,分别保留原类型。时间戳单位为 Unix 秒;不要套用 Activation V2 的 **`orderExpireIn`**。
# SDK 与库 (/zh/docs/sdks)
## 选择 SDK [#选择-sdk]
SDK 均覆盖 Activation V2、Rental 和 Private Email 的全部 56 个方法,可根据应用选择语言与执行方式。Alternative API 不包含在内。
六种 SDK 的 Alpha 版本均已公开发布,源码位于 SMSPVA 官方 GitHub 仓库。可从下表选择软件包并通过对应的公共仓库安装。所有 SDK 均使用 MIT 许可证。
| 软件包 | 环境要求 | 状态 | 版本 |
| --- | --- | --- | --- |
| [PyPI 上的 Python SDK](https://pypi.org/project/smspva-sdk/) | Python 3.10 或更高版本 | 已发布 Alpha,同步与异步 | **`0.1.0a2`** |
| [npm 上的 JavaScript / TypeScript SDK](https://www.npmjs.com/package/smspva-sdk) | Node.js 22.16 或更高版本 | 已发布 Alpha,ESM 与 CommonJS | **`0.1.0-alpha.2`** |
| [PHP SDK](https://packagist.org/packages/smspva/sdk) | PHP 8.0+, cURL 和 JSON | 已发布 Alpha,同步 | **`0.1.0-alpha.1`** |
| [Go SDK](https://pkg.go.dev/github.com/SMSPVA/smspva-go) | Go 1.22+ | 已发布 Alpha,同步,支持 context | **`v0.1.0-alpha.1`** |
| [C# / .NET](https://www.nuget.org/packages/Smspva.Sdk/0.1.0-alpha.1) | .NET 8+ | 已发布 Alpha,异步,支持 CancellationToken | **`0.1.0-alpha.1`** |
| [Java SDK](https://central.sonatype.com/artifact/com.smspva/smspva-sdk/0.1.0-alpha.1) | Java 17+ | 已发布 Alpha,同步 | **`0.1.0-alpha.1`** |
## 版本与更新 [#版本与更新]
已发布的 SDK 均为 Alpha 版本。如需可重复的安装结果,请固定版本,并在升级前查看仓库的更新日志。Python 使用 **`0.1.0a2`**,JavaScript/TypeScript 使用 **`0.1.0-alpha.2`**,PHP、Go、C#/.NET 和 Java 使用 **`0.1.0-alpha.1`**(Go 命令中带 **`v`** 前缀)。这些都是预发布版本,尚非稳定版。
## Python [#python]
从 [PyPI](https://pypi.org/project/smspva-sdk/) 安装 Python SDK。使用 **`--pre`** 允许安装 Alpha 版本:
```sh
python -m pip install --pre smspva-sdk
```
如需固定当前版本,使用 **`python -m pip install smspva-sdk==0.1.0a2`**。源码、README 和问题跟踪位于 [GitHub 上的 SMSPVA/smspva-python](https://github.com/SMSPVA/smspva-python)。
同步应用使用 **`SMSPVA`**。下面的示例查询 Activation 账户余额,并获取当前的 Rental 国家列表和 Email 提供商列表:
```python
import os
from smspva import SMSPVA
with SMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
print(client.activation.get_balance())
print(client.rental.get_countries())
print(client.email.get_providers())
```
异步应用使用 **`AsyncSMSPVA`**,通过 **`await`** 调用相同的方法:
```python
import asyncio
import os
from smspva import AsyncSMSPVA
async def main():
async with AsyncSMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
print(await client.activation.get_balance())
print(await client.rental.get_countries())
print(await client.email.get_providers())
asyncio.run(main())
```
上下文管理器会在退出时关闭连接池。如果自行管理客户端,请在使用完毕后调用 **`close()`** 或 **`await aclose()`**。
## JavaScript 和 TypeScript [#javascript-和-typescript]
从 [npm](https://www.npmjs.com/package/smspva-sdk) 安装 JavaScript 和 TypeScript SDK。**`alpha`** 标签指向最新的 Alpha 版本:
```sh
npm install smspva-sdk@alpha
```
如需固定当前版本,使用 **`npm install smspva-sdk@0.1.0-alpha.2`**。源码、README 和问题跟踪位于 [GitHub 上的 SMSPVA/smspva-js](https://github.com/SMSPVA/smspva-js)。
```ts
import { SMSPVA } from 'smspva-sdk';
const client = new SMSPVA({ apiKey: process.env.SMSPVA_API_KEY });
console.log(await client.activation.getBalance());
console.log(await client.rental.getCountries());
console.log(await client.email.getProviders());
```
同样的代码也适用于 JavaScript。CommonJS 使用 **`const { SMSPVA } = require('smspva-sdk')`** 导入。请在服务器上运行 SDK,不要把 API 密钥放进浏览器代码中。
## PHP [#php]
使用 Composer 从 [Packagist 安装 PHP SDK](https://packagist.org/packages/smspva/sdk):
```sh
composer require "smspva/sdk:^0.1@alpha"
```
如需固定此版本,使用 **`composer require smspva/sdk:0.1.0-alpha.1`**。源码、README 和问题跟踪位于 [GitHub 上的 SMSPVA/smspva-php](https://github.com/SMSPVA/smspva-php)。
```php
activation->getBalance());
print_r($client->rental->getCountries());
print_r($client->email->getProviders());
```
PHP 方法接收参数数组,生成的 PHPDoc 会注明字段类型。响应是关联数组。客户端为同步模式,需要 cURL 扩展。
## Go [#go]
从带版本标签的模块安装 [Go SDK](https://pkg.go.dev/github.com/SMSPVA/smspva-go):
```sh
go get github.com/SMSPVA/smspva-go@v0.1.0-alpha.1
```
源码、README 和问题跟踪位于 [GitHub 上的 SMSPVA/smspva-go](https://github.com/SMSPVA/smspva-go)。SDK 仅使用标准库。
Go SDK 是带版本标签的 GitHub 模块。**`pkg.go.dev`** 展示 README 和自动生成的包文档,无需另行上传代码。安装时不需要注册 pkg.go.dev 账号。新版本由官方仓库中的 Git 标签标识。
```go
package main
import (
"context"
"fmt"
"log"
"os"
smspva "github.com/SMSPVA/smspva-go"
)
func printResult(response smspva.Response, err error) {
if err != nil { log.Fatal(err) }
fmt.Println(string(response.Body))
}
func main() {
client, err := smspva.New(smspva.Options{APIKey: os.Getenv("SMSPVA_API_KEY")})
if err != nil { log.Fatal(err) }
defer client.CloseIdleConnections()
ctx := context.Background()
printResult(client.Activation.GetBalance(ctx))
printResult(client.Rental.GetCountries(ctx))
printResult(client.Email.GetProviders(ctx))
}
```
将程序保存为 **`main.go`**,然后运行 **`go run .`**。方法接收 **`context.Context`**,有参数时使用类型化结构体,原始 JSON 响应位于 **`Response.Body`**。
## C# / .NET [#c--net]
从 [NuGet 安装 .NET SDK](https://www.nuget.org/packages/Smspva.Sdk/0.1.0-alpha.1)。源码、README 和问题跟踪位于 [GitHub 上的 SMSPVA/smspva-dotnet](https://github.com/SMSPVA/smspva-dotnet):
```sh
dotnet add package Smspva.Sdk --version 0.1.0-alpha.1
```
```csharp
using System;
using Smspva;
using var client = new SmspvaClient(Environment.GetEnvironmentVariable("SMSPVA_API_KEY"));
Console.WriteLine(await client.Activation.GetBalanceAsync());
Console.WriteLine(await client.Rental.GetCountriesAsync());
Console.WriteLine(await client.Email.GetProvidersAsync());
```
C# 方法为异步模式,支持 **`CancellationToken`**。请求使用类型化 record,响应为 **`JsonElement`**。
## Java [#java]
从 [Maven Central 安装 Java SDK](https://central.sonatype.com/artifact/com.smspva/smspva-sdk/0.1.0-alpha.1),在应用的 **`pom.xml`** 中加入以下依赖:
```xml
com.smspva
smspva-sdk
0.1.0-alpha.1
```
```java
import com.smspva.sdk.SmsPva;
public class Example {
public static void main(String[] args) {
try (SmsPva client = new SmsPva(System.getenv("SMSPVA_API_KEY"))) {
System.out.println(client.activation().getBalance());
System.out.println(client.rental().getCountries());
System.out.println(client.email().getProviders());
}
}
}
```
源码、README 和问题跟踪位于 [GitHub 上的 SMSPVA/smspva-java](https://github.com/SMSPVA/smspva-java)。Java 方法为同步模式,接收类型化 **`Requests`** record,返回 **`JsonNode`**。此 Alpha 版本没有 Java 异步封装或轮询辅助方法。
## 参数与响应 [#参数与响应]
请从实时参考列表中获取国家、服务和提供商代码。例如,在 Python 中调用 **`email.get_providers()`**,或在 JavaScript 中调用 **`email.getProviders()`**,再将选定的 **`pcode`** 传给 **`get_data(pcode=...)`** 或 **`getData({ pcode: ... })`**。公开查询方法无需 API 密钥,也不会发送客户端配置的密钥。
SDK 保留文档中的 HTTP 方法、实际请求参数名、响应代码和 JSON 值类型。Python 与 JavaScript 包含生成的响应类型;PHP 返回关联数组;Go 将原始 JSON 放在 **`Response.Body`** 中;C# 使用 **`JsonElement`**;Java 使用 **`JsonNode`**。各语言的请求参数均有类型定义或说明。
查询 Rental 多服务号码数量时,请明确传入 **`dtype`** 和 **`dcount`**。SDK 要求提供这两个参数,因为接口文档提醒此方法不能依赖服务器的默认值。
## 等待短信与处理错误 [#等待短信与处理错误]
Activation 的 **`receive_sms`** / **`receiveSms`** 遇到 HTTP **`202`** 和 **`SMS_NOT_YET_RECEIVED`** 时,会返回原始的等待响应,可用 **`is_pending`** / **`isPending`** 判断。创建 Email 订单时,表示无库存的 **`status=2`** 也会作为原始结果返回,可用 **`is_no_stock`** / **`isNoStock`** 判断。
需要重复查询短信时,可使用 Python 的 **`activation.wait_for_sms`** 或 JavaScript 的 **`activation.waitForSms`**。获取号码时保存订单到期时间,再将同一个截止时间传入 **`expires_at`**(Unix 秒)或 **`expiresAt`**(Unix 毫秒)。收到等待响应后,辅助方法至少间隔五秒再查询;到期或遇到错误时停止。它不会创建或取消订单。接收新短信可能触发扣费。
每次调用 **`receive_sms`** / **`receiveSms`** 只发送一个 HTTP 请求。Python 和 JavaScript 的等待辅助方法会立即发送第一次请求;每次收到等待响应后,默认暂停五秒再查询。可在 Python 中设置 **`interval=15`**,或在 JavaScript 中设置 **`intervalMs: 15_000`**,将暂停时间改为 15 秒。最小间隔是辅助方法的规则,不是整个 API 的限流规定。**`await`** 等待辅助方法的结果,同时允许其他异步任务在请求和暂停期间继续运行;Python 同步客户端则会阻塞调用线程。
Python、JavaScript 和 PHP 通过 **`ApiError`** 报告 API 失败;C# 和 Java 使用 **`ApiException`**;Go 返回 **`APIError`**。这些错误保留 HTTP 状态、API 错误代码和原始响应。协议错误与网络传输错误会分别报告。C# 支持取消令牌,Go 支持通过 context 取消请求。
SDK 不会自动重试任何请求。付费操作或修改状态的操作如果中途断开连接,可能无法确定是否已完成。重试前请先查询当前订单,避免重复购买。GET 方法也可能修改状态或触发扣费。
默认超时为 30 秒。Python 将其应用于 HTTPX 的每项网络操作;JavaScript 则应用于整个请求,包括读取响应正文。可以通过 Python 的 **`timeout`** 或 JavaScript 的 **`timeoutMs`** 修改。JavaScript 还支持通过 **`signal`** 选项传入 **`AbortSignal`** 来取消请求。
PHP、Go 和 C# 默认也会限制整个请求的耗时。Java 与 Python 一样使用网络操作超时,而不是整个响应的严格截止时间。Java 和 PHP 为同步客户端。各语言的超时配置和错误类型请参考 SDK 的 README。
也可以继续结合[快速入门中的 HTTP 示例](/zh/docs/quickstart)使用 SDK。各方法页面仍是核对参数、响应代码和重要警告的依据。