AdaptGroup打开控制台
VPN 基础设施

将 VPN 订阅集成到您的产品中。

从网站、应用、Telegram 机器人或内部服务创建和管理订阅,VPN 基础设施由 AdaptGroup 负责运行。

Base URL
https://network-api.adaptgroup.app
身份验证
X-Api-Key
功能
套餐、订阅、余额、Webhooks
速率限制
100 次请求 / 60 秒

创建订阅

套餐成本会从集成余额中扣除。试用套餐无法通过 API 创建。

POST/subs/create
cURL
export ADAPTGROUP_API_KEY="YOUR_API_KEY"

curl --request POST \
  --url https://network-api.adaptgroup.app/subs/create \
  --header "Content-Type: application/json" \
  --header "X-Api-Key: $ADAPTGROUP_API_KEY" \
  --data '{
    "api_key_id": 1,
    "plan_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "external_user_id": "user_123"
  }'
Python
import os
import requests

response = requests.post(
    "https://network-api.adaptgroup.app/subs/create",
    headers={
        "Content-Type": "application/json",
        "X-Api-Key": os.environ["ADAPTGROUP_API_KEY"],
    },
    json={
        "api_key_id": 1,
        "plan_uuid": "550e8400-e29b-41d4-a716-446655440000",
        "external_user_id": "user_123",
    },
    timeout=10,
)

response.raise_for_status()
subscription = response.json()
Node.js
const response = await fetch("https://network-api.adaptgroup.app/subs/create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Api-Key": process.env.ADAPTGROUP_API_KEY,
  },
  body: JSON.stringify({
    api_key_id: 1,
    plan_uuid: "550e8400-e29b-41d4-a716-446655440000",
    external_user_id: "user_123",
  }),
});

if (!response.ok) {
  throw new Error(`VPN API request failed: ${response.status}`);
}

const subscription = await response.json();
PHP
<?php

$payload = json_encode([
    'api_key_id' => 1,
    'plan_uuid' => '550e8400-e29b-41d4-a716-446655440000',
    'external_user_id' => 'user_123',
]);

$request = curl_init('https://network-api.adaptgroup.app/subs/create');

curl_setopt_array($request, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-Api-Key: ' . getenv('ADAPTGROUP_API_KEY'),
    ],
    CURLOPT_POSTFIELDS => $payload,
]);

$response = curl_exec($request);

if ($response === false) {
    throw new RuntimeException(curl_error($request));
}

curl_close($request);
$subscription = json_decode($response, true, flags: JSON_THROW_ON_ERROR);
Go
package main

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

func main() {
    payload, err := json.Marshal(map[string]any{
        "api_key_id":      1,
        "plan_uuid":       "550e8400-e29b-41d4-a716-446655440000",
        "external_user_id": "user_123",
    })
    if err != nil {
        panic(err)
    }

    req, err := http.NewRequest(
        http.MethodPost,
        "https://network-api.adaptgroup.app/subs/create",
        bytes.NewReader(payload),
    )
    if err != nil {
        panic(err)
    }

    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-Api-Key", os.Getenv("ADAPTGROUP_API_KEY"))

    client := &http.Client{Timeout: 10 * time.Second}
    response, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer response.Body.Close()

    if response.StatusCode != http.StatusOK {
        panic(fmt.Sprintf("VPN API request failed: %s", response.Status))
    }
}
Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Main {
    public static void main(String[] args) throws Exception {
        String apiKey = System.getenv("ADAPTGROUP_API_KEY");

        String payload = """
            {
              "api_key_id": 1,
              "plan_uuid": "550e8400-e29b-41d4-a716-446655440000",
              "external_user_id": "user_123"
            }
            """;

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://network-api.adaptgroup.app/subs/create"))
            .header("Content-Type", "application/json")
            .header("X-Api-Key", apiKey)
            .POST(HttpRequest.BodyPublishers.ofString(payload))
            .build();

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

        if (response.statusCode() != 200) {
            throw new IllegalStateException(response.body());
        }

        String subscription = response.body();
        System.out.println(subscription);
    }
}
C#
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add(
    "X-Api-Key",
    Environment.GetEnvironmentVariable("ADAPTGROUP_API_KEY")
);

var payload = JsonSerializer.Serialize(new
{
    api_key_id = 1,
    plan_uuid = "550e8400-e29b-41d4-a716-446655440000",
    external_user_id = "user_123",
});

using var body = new StringContent(
    payload,
    Encoding.UTF8,
    "application/json"
);

using var response = await client.PostAsync("https://network-api.adaptgroup.app/subs/create", body);
response.EnsureSuccessStatusCode();

var subscription = await response.Content.ReadFromJsonAsync<JsonElement>();
Ruby
require "json"
require "net/http"
require "uri"

uri = URI("https://network-api.adaptgroup.app/subs/create")
request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["X-Api-Key"] = ENV.fetch("ADAPTGROUP_API_KEY")
request.body = {
  api_key_id: 1,
  plan_uuid: "550e8400-e29b-41d4-a716-446655440000",
  external_user_id: "user_123"
}.to_json

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

unless response.is_a?(Net::HTTPSuccess)
  raise "VPN API request failed: #{response.code}"
end

subscription = JSON.parse(response.body)
Rust
use reqwest::blocking::Client;
use serde_json::{json, Value};
use std::env;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let subscription: Value = Client::new()
        .post("https://network-api.adaptgroup.app/subs/create")
        .header("Content-Type", "application/json")
        .header("X-Api-Key", env::var("ADAPTGROUP_API_KEY")?)
        .json(&json!({
            "api_key_id": 1,
            "plan_uuid": "550e8400-e29b-41d4-a716-446655440000",
            "external_user_id": "user_123"
        }))
        .send()?
        .error_for_status()?
        .json()?;

    println!("{subscription:#}");
    Ok(())
}

仅在服务器端保存 X-Api-Key。这些示例不会从浏览器发送请求。

200 OK响应
{
  "success": true,
  "subscription_uuid": "770fa622-a4bd-63f6-c938-668877662222",
  "subscription_url": "https://network-api.adaptgroup.app/sub/770fa622-a4bd-63f6-c938-668877662222",
  "plan_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "external_user_id": "user_123",
  "end_date": "2026-06-01T12:00:00",
  "devices": 3,
  "days": 30,
  "traffic_limit_bytes": null,
  "balance": "96.50"
}

API 返回可直接使用的订阅链接。

将 subscription_url 直接交给用户的 VPN 客户端。响应还包含订阅 ID、结束时间、设备限制、流量限制和剩余余额。