TÀI LIỆU API V2

Tín dụng, tính phí và mức sử dụng trong API V2

Đọc số dư GenderAPI.io dùng chung và hiểu chi phí tín dụng của V2, kết quả không xác định bị tính phí, hoàn trả, số dư âm và thời điểm đặt lại dùng thử theo IP.

Tín dụng, kết quả không xác định và mức sử dụng

Kết quả thành công với gender null bị tính phí theo mức của chế độ đã chọn. Xác thực số điện thoại tốn 1 tín dụng kể cả khi valid là false. Lỗi xác thực trước khi tính phí và dự đoán thất bại không tiêu tốn tín dụng sau khi việc hoàn trả được xác nhận.

Chỉ cần số dư ban đầu dương là đủ để bắt đầu một thao tác đơn lẻ hoặc một lô. Lần tính phí cuối cùng có thể làm số dư âm: 1 tín dụng ban đầu trừ một thao tác AI 2 tín dụng còn lại -1. Số dư bằng 0 hoặc âm sẽ chặn các thao tác bị tính phí mới. Việc hoàn trả vẫn được phép.

Đọc meta.usage.billing_status: not_charged nghĩa là không trừ tín dụng (charged_credits: 0); confirmed nghĩa là đã biết phí thực tính; unconfirmed nghĩa là charged_credits là null và cần kiểm tra kết quả. remaining_credits có thể âm, hoặc null nếu không có. Đây là ảnh chụp số dư tại thời điểm hoàn tất và có thể thay đổi do các yêu cầu đồng thời.

GET /usage miễn phí. Yêu cầu này trả về remaining_credits và expires_at, cùng resets_at, limit và period_seconds khi dùng thử theo IP. Giới hạn dùng thử là 10 và period_seconds là 86400; các trường này là null với tài khoản dùng khóa API. resets_at không phải thời điểm hết hạn gói đăng ký.

V1 và V2 dùng chung một số dư. Các cơ chế ghi số dư hiện có của V1 có thể chạy đồng thời với V2; đừng dựa vào bảo đảm tính phí đúng một lần giữa hai phiên bản.

Phản hồi JSON minh họa
{
  "data": {
    "remaining_credits": 9,
    "expires_at": "2026-09-26T12:00:00.000Z",
    "resets_at": "2026-09-26T12:00:00.000Z",
    "limit": 10,
    "period_seconds": 86400
  },
  "meta": {
    "request_id": "11111111-1111-4111-8111-111111111111",
    "duration_ms": 12,
    "access": {
      "mode": "ip_trial",
      "reason": "api_key_missing"
    },
    "usage": {
      "charged_credits": 0,
      "remaining_credits": 9,
      "billing_status": "not_charged",
      "resets_at": "2026-09-26T12:00:00.000Z",
      "limit": 10,
      "period_seconds": 86400
    }
  }
}

Kiểm tra số dư hiện tại

GET /api/v2/usage miễn phí, dùng xác thực Bearer và không có tham số truy vấn. Nếu không gửi khóa, yêu cầu sẽ đọc hạn mức dùng thử theo IP hiện tại.

Chọn ngôn ngữ lập trình. Thiết lập khóa API, sau đó chạy ví dụ trên máy chủ của bạn.

Việc đọc số dư này không tốn tín dụng, nhưng vẫn được tính vào giới hạn yêu cầu.

Trước khi chạy: quyền truy cập và xử lý lỗi

Chạy các ví dụ này trên máy chủ của bạn. Đặt GENDERAPI_API_KEY trong biến môi trường của tiến trình bằng khóa API hiện có. Xác nhận meta.access.mode là api_key: khóa không được nhận diện có thể chuyển sang dùng thử theo IP.

Với phản hồi JSON HTTP 4xx và 5xx, ví dụ giữ nguyên nội dung lỗi và kết thúc với mã thoát khác 0. Kiểm tra code, action và meta.usage.billing_status trước khi thử lại.

Hướng dẫn về lỗi và thử lại →
cURL
curl --silent --show-error --fail-with-body --max-time 30 \
  --request GET 'https://api.genderapi.io/api/v2/usage' \
  --header "Authorization: Bearer ${GENDERAPI_API_KEY:?Set GENDERAPI_API_KEY}"

cURL 7.76+ trong shell POSIX. Chạy trong terminal. Tài liệu môi trường chạy

JavaScript / Node.js
// Server-side Node.js. Save as example.mjs.
const apiKey = process.env.GENDERAPI_API_KEY;
if (!apiKey) throw new Error("Set GENDERAPI_API_KEY");

const response = await fetch("https://api.genderapi.io/api/v2/usage", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${apiKey}`,
  },
  signal: AbortSignal.timeout(30_000),
  redirect: "error",
});
const raw = await response.text();
if (!(response.headers.get("content-type") ?? "").includes("json")) {
  throw new Error(`HTTP ${response.status}: expected JSON; request ID ${response.headers.get("x-request-id")}`);
}
const result = JSON.parse(raw); // Also accepts application/problem+json.
if (!response.ok) {
  console.error(`HTTP ${response.status}`, result);
  process.exitCode = 1; // A retry is a new operation; inspect billing first.
} else {
  console.log(JSON.stringify(result, null, 2));
  // For batches, inspect every item: HTTP 200 may contain item errors.
}

Node.js 22+; fetch tích hợp sẵn. Lưu thành example.mjs và chạy node example.mjs. Tài liệu môi trường chạy

Python
import json
import os
import sys
import urllib.error
import urllib.request

api_key = os.environ.get("GENDERAPI_API_KEY")
if not api_key:
    raise RuntimeError("Set GENDERAPI_API_KEY")

class NoRedirect(urllib.request.HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None

request = urllib.request.Request(
    "https://api.genderapi.io/api/v2/usage",
    method="GET",
    headers={
        "Authorization": "Bearer " + api_key,
    },
)
opener = urllib.request.build_opener(NoRedirect())
try:
    response = opener.open(request, timeout=30)
except urllib.error.HTTPError as error:
    response = error  # Keep the Problem Details body on non-2xx responses.
with response:
    status = response.status
    raw = response.read().decode("utf-8")
    if "json" not in response.headers.get("Content-Type", ""):
        raise RuntimeError(f"HTTP {status}: expected a JSON response")
    result = json.loads(raw)
print(json.dumps(result, indent=2), file=sys.stderr if status >= 300 else sys.stdout)
if not 200 <= status < 300:
    sys.exit(1)  # Inspect code, action and billing before retrying.
# For batches, inspect every item even when HTTP status is 200.

Python 3.10+; thư viện chuẩn. Lưu thành example.py và chạy python3 example.py. Tài liệu môi trường chạy

PHP
<?php
$apiKey = getenv('GENDERAPI_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set GENDERAPI_API_KEY');
}

$ch = curl_init('https://api.genderapi.io/api/v2/usage');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
    ],
]);
$raw = curl_exec($ch);
if ($raw === false) {
    throw new RuntimeException(curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE) ?: '';
curl_close($ch);
if (strpos($contentType, 'json') === false) {
    throw new RuntimeException("HTTP $status: expected a JSON response");
}
$result = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
$output = json_encode($result, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR) . PHP_EOL;
if ($status < 200 || $status >= 300) {
    fwrite(STDERR, $output); // Preserve the Problem Details body.
    exit(1);
}
echo $output;
// For batches, inspect every item; HTTP 200 can contain item errors.

PHP 8+ với tiện ích mở rộng cURL. Lưu thành example.php và chạy php example.php. Tài liệu môi trường chạy

Java
import java.net.URI;
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 GenderApiExample {
    private static String requiredEnv(String name) {
        String value = System.getenv(name);
        if (value == null || value.isBlank()) throw new IllegalStateException("Set " + name);
        return value;
    }

    public static void main(String[] args) throws Exception {
        String apiKey = requiredEnv("GENDERAPI_API_KEY");
        HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .followRedirects(HttpClient.Redirect.NEVER)
            .build();
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.genderapi.io/api/v2/usage"))
            .timeout(Duration.ofSeconds(30))
            .header("Authorization", "Bearer " + apiKey)
            .GET()
            .build();
        HttpResponse<String> response = client.send(request,
            HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
        if (!response.headers().firstValue("content-type").orElse("").contains("json")) {
            throw new IllegalStateException("HTTP " + response.statusCode() + ": expected JSON");
        }
        // JSON text; parse with your application's JSON library when integrating.
        if (response.statusCode() < 200 || response.statusCode() >= 300) {
            System.err.println(response.body()); // Includes Problem Details.
            System.exit(1);
        }
        System.out.println(response.body());
        // For batches, inspect each item's data or error, including on HTTP 200.
    }
}

Java 17+; HTTP client chuẩn. Lưu thành GenderApiExample.java và chạy java GenderApiExample.java. Tài liệu môi trường chạy

C# / .NET
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

string RequiredEnv(string name) =>
    !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(name))
        ? Environment.GetEnvironmentVariable(name)!
        : throw new InvalidOperationException($"Set {name}");

var apiKey = RequiredEnv("GENDERAPI_API_KEY");
using var handler = new HttpClientHandler { AllowAutoRedirect = false };
using var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.genderapi.io/api/v2/usage");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);

using var response = await client.SendAsync(request);
var raw = await response.Content.ReadAsStringAsync();
if (!(response.Content.Headers.ContentType?.MediaType?.Contains("json") ?? false))
    throw new InvalidOperationException($"HTTP {(int)response.StatusCode}: expected JSON");
using var result = JsonDocument.Parse(raw);
if (!response.IsSuccessStatusCode)
{
    Console.Error.WriteLine(result.RootElement); // Preserve Problem Details.
    Environment.ExitCode = 1;
}
else
{
    Console.WriteLine(result.RootElement);
    // For batches, inspect every item even on HTTP 200.
}

Ứng dụng console .NET 8+. Dùng làm Program.cs trong một dự án console, sau đó chạy dotnet run. Tài liệu môi trường chạy

Go
package main

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

func requiredEnv(name string) string {
    value := os.Getenv(name)
    if value == "" { panic("Set " + name) }
    return value
}

func run() error {
    apiKey := requiredEnv("GENDERAPI_API_KEY")
    request, err := http.NewRequest("GET", "https://api.genderapi.io/api/v2/usage", nil)
    if err != nil { return err }
    request.Header.Set("Authorization", "Bearer " + apiKey)
    client := &http.Client{
        Timeout: 30 * time.Second,
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            return http.ErrUseLastResponse
        },
    }
    response, err := client.Do(request)
    if err != nil { return err }
    defer response.Body.Close()
    raw, err := io.ReadAll(response.Body)
    if err != nil { return err }
    if !strings.Contains(response.Header.Get("Content-Type"), "json") || !json.Valid(raw) {
        return fmt.Errorf("HTTP %d: expected a JSON response", response.StatusCode)
    }
    if response.StatusCode < 200 || response.StatusCode >= 300 {
        return fmt.Errorf("HTTP %d: %s", response.StatusCode, raw)
    }
    fmt.Println(string(raw))
    // For batches, inspect every item even on HTTP 200.
    return nil
}

func main() {
    if err := run(); err != nil {
        fmt.Fprintln(os.Stderr, err) // Keep Problem Details for error handling.
        os.Exit(1)
    }
}

Go 1.22+; thư viện chuẩn. Lưu thành main.go và chạy go run main.go. Tài liệu môi trường chạy

Trường phản hồi số dư

TrườngKiểuCó thể là nullVí dụMô tả
data.remaining_creditsintegerKhông99Số dư hiện tại của tài khoản hoặc dùng thử theo IP; có thể âm.
data.expires_atstringCónullThời điểm hết hạn của tài khoản hoặc dùng thử, theo UTC (ISO 8601), nếu có.
data.resets_atstringCó"2026-09-27T12:00:00.000Z"Thời điểm đặt lại dùng thử theo IP, theo UTC (ISO 8601); null với tài khoản dùng khóa API hoặc khi chưa biết.
data.limitintegerCó10Hạn mức dùng thử theo IP; null với tài khoản dùng khóa API.
data.period_secondsintegerCó86400Chu kỳ dùng thử theo IP tính bằng giây; null với tài khoản dùng khóa API.

Siêu dữ liệu về truy cập, tính phí và yêu cầu

TrườngKiểuCó thể là nullVí dụMô tả
meta.request_idstringKhông"550e8400-e29b-41d4-a716-446655440000"Mã định danh duy nhất của lần gửi HTTP này; cũng được gửi trong X-Request-ID.
meta.duration_msintegerKhông42Thời gian xử lý yêu cầu tính bằng mili giây.
meta.access.modestringKhông"api_key"api_key, ip_trial hoặc unauthenticated. Khi dùng tài khoản trả phí, hãy kiểm tra giá trị là api_key.
meta.access.reasonstringCónullLý do chuyển sang dùng thử: api_key_missing, api_key_invalid hoặc api_key_not_found; trường hợp khác là null.
meta.usage.charged_creditsintegerCó1Số tín dụng thực tính. Bằng 0 trước khi tính phí hoặc sau khi hoàn trả toàn bộ đã được xác nhận; null khi việc tính phí chưa được xác nhận.
meta.usage.remaining_creditsintegerCó99Số dư khi thao tác hoàn tất. Có thể âm; null khi không có thông tin hoặc việc tính phí chưa được xác nhận.
meta.usage.billing_statusstringKhông"confirmed"not_charged, confirmed hoặc unconfirmed. Kiểm tra trường này trước khi thử lại một dự đoán thất bại.
meta.usage.resets_atstringCó"2026-09-27T12:00:00.000Z"Thời điểm đặt lại dùng thử theo IP, theo UTC (ISO 8601); null với tài khoản dùng khóa API hoặc khi chưa biết.
meta.usage.limitintegerCó10Hạn mức dùng thử theo IP; null với tài khoản dùng khóa API.
meta.usage.period_secondsintegerCó86400Chu kỳ dùng thử theo IP tính bằng giây; null với tài khoản dùng khóa API.