크레딧·요청 한도 V5 (beta)

수집에 크레딧이 언제, 얼마나 쓰이는지와 1분에 보낼 수 있는 요청 수입니다.

API 로 수집해도 화면에서 수집할 때와 같은 규칙으로 크레딧이 쓰입니다. 봇·설정·주기·데이터셋을 읽거나 바꾸는 v5 요청에는 크레딧이 들지 않고, 수집이 데이터를 저장할 때만 쓰입니다.

크레딧이 쓰이는 방식

  • 기본은 데이터 한 줄마다 봇의 건당 크레딧. 수집이 저장한 데이터 한 줄마다 그 봇의 건당 크레딧이 빠집니다. 기본 계산으로는 건당 5 크레딧인 봇이 1,280줄을 모으면 6,400 크레딧입니다. 다만 한 번에 많은 줄을 묶어 저장하는 일부 수집 방식에는 배수가 붙을 수 있고, 계약으로 단가를 따로 정한 계정은 그 단가를 씁니다.
  • 0건이면 0 크레딧. 데이터를 하나도 저장하지 못한 수집에는 크레딧이 들지 않습니다. 이유는 데이터셋의 empty_reason에 있습니다.
  • 중복으로 버린 줄은 0. 중복으로 판정돼 저장하지 않은 줄에는 크레딧이 들지 않습니다. 무엇을 중복으로 보는지는 봇의 수집 방식에 따라 다릅니다 — 새 수집에서 같은 내용을 다시 저장하면 다시 쓰일 수 있습니다.
  • 시작할 때 잔액을 봅니다. 크레딧이 모자라면 수집이 시작되지 않고 402 CREDIT_EXHAUSTED, 이용권이 끝났으면 402 TICKET_EXPIRED입니다. 주기 수집은 그 회차를 건너뛰고 주기 실행 결과에 이유를 남깁니다 — 크레딧 부족은 insufficient_credit, 이용권 문제는 ticket_expired 등.
  • 실제로 쓴 양은 데이터셋에. 데이터셋에 쓴 크레딧은 credits_used(정수)가 정답입니다. 결과를 이어 쌓는 설정(union)으로 앞 데이터셋에 이어 저장했다면, 이 값은 이번 수집만이 아니라 그 데이터셋에 쌓인 수집 전체의 합입니다.
요청 예시
curl 'https://www.hashscraper.com/v5/api/datasets/239758028' \
  -H 'Authorization: Bearer YOUR_API_KEY'
응답 예시 200
{
  "result": "success",
  "version": "v5",
  "request_id": "req_5a8c1f1c-9b2d-4e7c-9abf-3f7e0a4d1b21",
  "elapsed_sec": 0.0123,
  "data": {
    "id": 239758028,
    "bot": {
      "id": "8f3a7c1e9b5d24f6",
      "name": "Sample shopping bot"
    },
    "status": "done",
    "data_count": 1280,
    "union": false,
    "trigger": "api",
    "credits_used": 6400,
    "created_at": "2026-10-04T09:00:02+09:00",
    "updated_at": "2026-10-04T09:00:02+09:00",
    "plan": null,
    "inputs": {
      "param1": {
        "name": "Keyword",
        "value": "sneakers"
      }
    },
    "started_at": "2026-10-04T09:00:02+09:00",
    "elapsed_sec": 94
  }
}
응답 예시 402
{
  "result": "error",
  "version": "v5",
  "request_id": "req_5a8c1f1c-9b2d-4e7c-9abf-3f7e0a4d1b21",
  "code": "CREDIT_EXHAUSTED",
  "message": "Credits exhausted.",
  "elapsed_sec": 0.0011
}

봇마다 다른 건당 크레딧

건당 크레딧은 봇마다 다릅니다. 목록·댓글처럼 가벼운 데이터는 적게, 상세 정보나 AI 분석이 들어가는 데이터는 많이 듭니다.

가격은 바뀔 수 있어 이 문서에 숫자를 적어 두지 않습니다. 아래 두 곳이 늘 지금 값을 보여 줍니다.

  • 봇 소개 — 가입하지 않아도 공개 봇마다 건당 크레딧을 볼 수 있습니다.
  • GET /v5/api/bots·GET /v5/api/bots/{bot_id} — 응답의 credit_per_item(정수)입니다.
요청 예시
curl 'https://www.hashscraper.com/v5/api/bots/8f3a7c1e9b5d24f6' \
  -H 'Authorization: Bearer YOUR_API_KEY'
응답 예시 200
{
  "result": "success",
  "version": "v5",
  "request_id": "req_5a8c1f1c-9b2d-4e7c-9abf-3f7e0a4d1b21",
  "elapsed_sec": 0.0123,
  "data": {
    "id": "8f3a7c1e9b5d24f6",
    "name": "Sample shopping bot",
    "description": "Collects product lists by keyword.",
    "schedule_group": null,
    "union": false,
    "created_at": "2026-08-12T10:21:05+09:00",
    "updated_at": "2026-10-01T18:02:40+09:00",
    "worker_source": {
      "name": "Shopping list",
      "version": 12,
      "updated_at": "2026-09-20T11:00:00+09:00",
      "price": 5
    },
    "credit_per_item": 5,
    "plans_count": 2,
    "active_plans": [
      {
        "id": "512",
        "name": "주기 2",
        "label": "매주 월요일 09:00 (KST)"
      }
    ],
    "period_summary": "주기 2 · 매주 월요일 09:00 (KST)",
    "next_run_at": "2026-10-05T09:00:00+09:00",
    "latest_dataset": {
      "id": 239758028,
      "status": "done",
      "data_count": 1280,
      "trigger": "period",
      "created_at": "2026-09-28T09:00:03+09:00"
    }
  }
}

요청 한도

요청은 IP 주소 하나당 1분에 150번을 기준으로 받습니다. API 키가 아니라 요청을 보내는 곳의 IP 주소로 셉니다 — 같은 서버의 여러 프로그램이 부르면 합쳐서 셉니다.

넘으면 HTTP 429가 옵니다. 본문은 다른 오류와 같은 JSON 이고 code 는 RATE_LIMITED 입니다. 응답 머리 Retry-After 에 다시 보내도 되기까지 남은 초가 들어 있으니, 그만큼 기다렸다 다시 보내세요. 수집 시작 요청을 다시 보낼 때는 같은 재시도 중복 방지 키를 씁니다.

이 숫자는 보장이 아니라 기준입니다. 조금 더 받아질 때도 있지만 거기에 기대지 마세요. 수집 상태 확인은 10~30초 간격이면 충분하고, 많은 봇을 한꺼번에 돌릴 때는 하나씩 부르지 말고 묶음 수집을 쓰세요.

응답 예시 429
{
  "result": "error",
  "version": "v5",
  "request_id": "req_5a8c1f1c-9b2d-4e7c-9abf-3f7e0a4d1b21",
  "code": "RATE_LIMITED",
  "message": "Rate limit exceeded.",
  "elapsed_sec": 0.0011
}
Python 예시
import time
import uuid
import requests


def request_with_backoff(method, url, headers=None, **kwargs):
    headers = dict(headers or {})
    if method != "GET":
        # one key per request — every retry of the same request reuses it
        headers.setdefault("Idempotency-Key", str(uuid.uuid4()))
    for attempt in range(8):
        res = requests.request(method, url, headers=headers, timeout=30, **kwargs)
        if res.status_code != 429 or attempt == 7:
            return res
        # a 429 carries Retry-After: the seconds left until the one-minute window resets
        retry_after = res.headers.get("Retry-After", "")
        time.sleep(int(retry_after) if retry_after.isdigit() else min(2 ** attempt, 30))
Node.js 예시
// Node.js 18+ (built-in fetch)
const { randomUUID } = require("node:crypto");
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function requestWithBackoff(method, url, { headers = {}, body } = {}) {
  const h = { ...headers };
  // one key per request — every retry of the same request reuses it
  if (method !== "GET") h["Idempotency-Key"] ??= randomUUID();
  if (body) h["Content-Type"] = "application/json";
  for (let attempt = 0; ; attempt++) {
    const res = await fetch(url, { method, headers: h, body: body ? JSON.stringify(body) : undefined });
    if (res.status !== 429 || attempt === 7) return res;
    // a 429 carries Retry-After: the seconds left until the one-minute window resets
    const wait = Number(res.headers.get("Retry-After")) || Math.min(2 ** attempt, 30);
    await sleep(wait * 1000);
  }
}

한 번에 다룰 수 있는 양

무엇한도자세히
목록 한 쪽(limit)최대 1,000건목록 이어 받기
묶음 수집(POST /collections/bulk)최대 100개수집
대량 수집(POST /collections/bulk_jobs)최대 5,000개수집
엑셀 입력 파일최대 20MB설정
주기 실행 결과 조회 범위최대 31일주기 실행 결과

함께 보면 좋은 가이드