API 문서 V2

GenderAPI.io V2 크레딧, 과금과 사용량

공유되는 GenderAPI.io 잔액을 확인하고 V2의 크레딧 비용, 과금되는 알 수 없는 결과, 크레딧 반환, 음수 잔액과 IP 체험 초기화 시각을 이해하세요.

크레딧, 알 수 없는 결과와 사용량

성공한 요청이 null 성별을 반환해도 선택한 모드의 요금대로 과금됩니다. 전화번호 검증은 valid가 false여도 1크레딧입니다. 과금 전의 검증 오류와, 크레딧 반환이 확인된 실패한 추정은 크레딧을 소모하지 않습니다.

시작 잔액이 0보다 크면 단일 요청이나 일괄 요청을 시작할 수 있습니다. 최종 차감으로 잔액이 음수가 될 수 있습니다. 예를 들어 1크레딧에서 2크레딧짜리 AI 작업을 하면 잔액은 -1이 됩니다. 잔액이 0 이하이면 새로 과금되는 작업이 차단됩니다. 크레딧 반환은 계속 처리됩니다.

meta.usage.billing_status를 확인하세요. not_charged는 차감이 없었다는 뜻(charged_credits: 0)이고, confirmed는 순 차감액이 확정되었다는 뜻이며, unconfirmed는 charged_credits가 null이어서 결과를 확인해야 한다는 뜻입니다. remaining_credits는 음수일 수 있으며, 확인할 수 없으면 null입니다. 이 값은 완료 시점의 스냅숏이며 동시에 실행되는 요청에 따라 달라질 수 있습니다.

GET /usage는 무료입니다. remaining_credits와 expires_at을 반환하며, IP 체험에서는 resets_at, limit, period_seconds도 반환합니다. IP 체험의 limit은 10, period_seconds는 86400이며, API 키 계정에서는 이 필드들이 null입니다. resets_at은 구독 만료 시각이 아닙니다.

V1과 V2는 잔액을 공유합니다. V1의 기존 잔액 갱신 처리가 V2와 경합할 수 있으므로, 버전을 넘나들어 과금이 정확히 한 번만 이루어진다고 전제하지 마세요.

설명용 JSON 응답
{
  "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
    }
  }
}

현재 잔액 확인하기

GET /api/v2/usage는 무료이며 쿼리 매개변수 없이 Bearer 인증을 사용합니다. 키를 생략하면 현재 IP 체험 한도를 조회합니다.

프로그래밍 언어를 선택하세요. API 키 설정하기, 그다음 서버에서 예시를 실행하세요.

이 잔액 조회에는 크레딧이 들지 않지만 요청 한도에는 포함됩니다.

실행하기 전에: 접근과 오류 처리

이 예시는 서버에서 실행하세요. 프로세스 환경 변수 GENDERAPI_API_KEY에 기존 API 키를 설정하세요. 인식되지 않는 키는 IP 체험으로 전환될 수 있으므로 meta.access.mode가 api_key인지 확인하세요.

HTTP 4xx 및 5xx JSON 응답에서는 오류 본문을 그대로 출력하고 0이 아닌 종료 코드를 반환합니다. 재시도하기 전에 code, action과 meta.usage.billing_status를 확인하세요.

오류와 재시도 가이드 →
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}"

POSIX 셸의 cURL 7.76+. 터미널에서 실행하세요. 런타임 문서

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. example.mjs로 저장하고 node example.mjs를 실행하세요. 런타임 문서

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+, 표준 라이브러리. example.py로 저장하고 python3 example.py를 실행하세요. 런타임 문서

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+, cURL 확장. example.php로 저장하고 php example.php를 실행하세요. 런타임 문서

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 클라이언트. GenderApiExample.java로 저장하고 java GenderApiExample.java를 실행하세요. 런타임 문서

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.
}

.NET 8+ 콘솔 애플리케이션. 콘솔 프로젝트의 Program.cs로 사용한 다음 dotnet run을 실행하세요. 런타임 문서

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+, 표준 라이브러리. main.go로 저장하고 go run main.go를 실행하세요. 런타임 문서

잔액 응답 필드

필드유형null 허용예시설명
data.remaining_creditsinteger아니요99현재 계정 또는 IP 체험 잔액이며, 음수일 수 있습니다.
data.expires_atstring예null확인할 수 있는 경우 계정 또는 IP 체험의 만료 시각(UTC, ISO 8601)입니다.
data.resets_atstring예"2026-09-27T12:00:00.000Z"IP 체험 초기화 시각(UTC, ISO 8601)입니다. API 키 계정이거나 알 수 없으면 null입니다.
data.limitinteger예10IP 체험 크레딧 한도이며, API 키 계정에서는 null입니다.
data.period_secondsinteger예86400IP 체험 기간(초)이며, API 키 계정에서는 null입니다.

접근, 과금과 요청 메타데이터

필드유형null 허용예시설명
meta.request_idstring아니요"550e8400-e29b-41d4-a716-446655440000"이 HTTP 시도의 고유 식별자이며 X-Request-ID로도 전송됩니다.
meta.duration_msinteger아니요42요청 처리 시간(밀리초)입니다.
meta.access.modestring아니요"api_key"api_key, ip_trial 또는 unauthenticated. 유료 계정을 사용할 때는 api_key인지 확인하세요.
meta.access.reasonstring예nullIP 체험으로 전환된 사유: api_key_missing, api_key_invalid 또는 api_key_not_found. 그 외에는 null입니다.
meta.usage.charged_creditsinteger예1차감된 순 크레딧입니다. 차감 전이나 전액 반환이 확인된 뒤에는 0이며, 과금이 미확정이면 null입니다.
meta.usage.remaining_creditsinteger예99작업 완료 시점의 잔액입니다. 음수일 수 있으며, 확인할 수 없거나 과금이 미확정이면 null입니다.
meta.usage.billing_statusstring아니요"confirmed"not_charged, confirmed 또는 unconfirmed. 실패한 추정을 재시도하기 전에 확인하세요.
meta.usage.resets_atstring예"2026-09-27T12:00:00.000Z"IP 체험 초기화 시각(UTC, ISO 8601)입니다. API 키 계정이거나 알 수 없으면 null입니다.
meta.usage.limitinteger예10IP 체험 크레딧 한도이며, API 키 계정에서는 null입니다.
meta.usage.period_secondsinteger예86400IP 체험 기간(초)이며, API 키 계정에서는 null입니다.