# API v2 크레딧, 청구 및 사용량

> 공유된 GenderAPI 잔액을 읽고 v2 크레딧 비용, 청구 가능한 알 수 없는 항목, 환불, 마이너스 잔액 및 IP 평가판 재설정 시간을 이해하세요.

Canonical HTML: https://www.genderapi.io/ko/docs/v2/credits-and-usage

Last reviewed: 2026-09-25

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

정상 완료된 예측이 gender: 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 /사용은 무료입니다. remaining_credits 및 expires_at를 반환합니다. IP 평가판의 경우 resets_at, limit 및 period_seconds도 반환합니다. 체험판 한도는 10학점, 기간은 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 평가판 허용량을 읽습니다.

서버에서 다음 예제를 실행하세요. 프로세스 환경에서 GENDERAPI_API_KEY를 기존 API 키로 설정합니다. meta.access.mode가 api_key인지 확인하세요. 인식되지 않은 키는 IP 평가판으로 대체될 수 있습니다.

이 잔액 읽기에는 크레딧이 필요하지 않습니다. 요청 비율 제한에는 여전히 포함됩니다.

HTTP 4xx 및 5xx JSON 응답은 오류 본문을 보존하고 0이 아닌 종료 상태를 반환합니다. 다시 시도하기 전에 code, action 및 meta.usage.billing_status를 확인하세요.

**cURL**

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

```bash
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}"
```

**JavaScript / Node.js**

Node.js 22+; 내장된 가져오기. example.mjs로 저장하고 node example.mjs를 실행합니다.

```javascript
// 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.
}
```

**Python**

Python 3.10+; 표준 라이브러리. example.py로 저장하고 python3 example.py를 실행합니다.

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

**PHP**

PHP 8+(cURL 확장 포함). example.php로 저장하고 php example.php를 실행합니다.

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

**Java**

Java 17+; 표준 HTTP 클라이언트. GenderApiExample.java로 저장하고 java GenderApiExample.java를 실행합니다.

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

**C# / .NET**

.NET 8+ 콘솔 애플리케이션. 콘솔 프로젝트에서 Program.cs로 사용한 후 dotnet run를 실행하세요.

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

**Go**

Go 1.22+; 표준 라이브러리. main.go로 저장하고 go run main.go를 실행합니다.

```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)
    }
}
```

- [모드별 AI 요금](https://www.genderapi.io/ko/docs/v2/ai-options)
- [확인되지 않은 청구 및 재시도](https://www.genderapi.io/ko/docs/v2/errors-and-retries)
