Базовий URL https://nftpars.app/api/v1. Версія контракту 1.1.0 — машинозчитувана специфікація:
public-v1.yaml (OpenAPI 3.1). Дані передаються в JSON; час — UTC (RFC 3339, Z); суми — цілі нанотон (1 TON = 109).
Автентифікація та ключі API
Створіть застосунок і ключ API у кабінеті. Передавайте його в Authorization: Bearer <key>. Ключ показується один раз і зберігається лише як захищений хеш. Під час ротації задайте перехідний період для клієнтів. У разі витоку негайно відкличте ключ.
Власник застосунку повинен мати чинний Telegram Premium, підтверджений NFTPARS. Сам по собі Telegram Login не підтверджує Premium. Якщо перевірка застаріє, запити повернуть 403 PREMIUM_REQUIRED або 403 PREMIUM_VERIFICATION_STALE; дані не видаляються, а доступ відновлюється після повторного підтвердження.
Ліміти застосовуються до кожного застосунку (ваш план указано на сторінці тарифів). Кожна відповідь містить X-RateLimit-Limit, X-RateLimit-Remaining і X-RateLimit-Reset (час Unix). За 429 враховуйте Retry-After.
Оплата
Для поповнення надішліть TON зі своїм особистим коментарем (кабінет → Оплата). Кошти зараховуються лише після перевірки в блокчейні.
Кожен запит спочатку резервує вартість, потім списує оплату лише за надані результати, звільняючи залишок. Незнайдені елементи, помилки й незавершені завдання не оплачуються.
Надіслати Idempotency-Key у POST і запитах оновлення. Повтор із тим самим ключем повертає початкову відповідь (Idempotent-Replayed: true) без повторного списання. X-NFTPARS-Charged-Nano показує вартість запиту.
Швидка відповідь і нове спостереження
Швидкий (за замовчуванням) одразу повертає значення з індексу зі статусом freshness FRESH, STALE або PENDING; ?max_age= задає допустимий вік свіжих даних. Свіжі дані (?refresh=true) запитує в індексатора нове спостереження й повертає 202 із завданням; опитуйте GET /jobs/{id}або підпишіться на job.completed вебхуки / через jobs канал WebSocket.
import time, uuid, requests
# Fresh mode: ask for a new observation. Use an Idempotency-Key so a retry never charges twice.
r = requests.get(f"{API}/gifts/SnoopDogg-534281/owner", params={"refresh": "true"},
headers={**headers, "Idempotency-Key": str(uuid.uuid4())}, timeout=15)
job = r.json()["data"]["job"] # HTTP 202
while job["status"] in ("QUEUED", "RUNNING"):
time.sleep(2)
job = requests.get(f"{API}/jobs/{job['id']}", headers=headers, timeout=15).json()["data"]
print(job["status"], job["billing"]) # only SUCCEEDED items are charged
Пакетні завдання
POST /gifts/batch із різними ідентифікаторами в межах пакетного ліміту вашого плану. mode: "cached" відповідає одразу; оплачуються лише знайдені елементи; mode: "fresh" створює завдання; оплачуються лише успішні елементи.
VERIFIED — поточний власник Telegram, підтверджений у verified_at.
HISTORICAL — останній відомий власник Telegram; не поточний власник.
WALLET_ONLY — подарунок зберігається в гаманці TON; особа в Telegram не мається на увазі.
HIDDEN, UNKNOWN, CONFLICT — достовірну поточну особу не визначено; за конфлікту перелічені всі спостережувані кандидати.
Актуальність оцінюється окремо від статусу. Кожен власник має sources (походження даних) та observed_at.
Фільтри пропозицій
Профілі фільтрів обмежують потік пропозицій застосунку (вебхуки та offers канал WebSocket) та результати пошуку/ринку: країна, добровільно вказаний гендер, колекції, діапазон цін і номерів, статус власника, мінімальна актуальність і ринковий статус. Тимчасові фільтри на 1, 2, 6, 24 години або власний термін замінюють постійний профіль і автоматично відновлюють його після завершення терміну. Країна й гендер доступні лише за добровільного зазначення та згоди власника; невідомі значення виключаються, якщо не задано unknown.<field> = "include". Спершу перевірте покриття.
# Two-hour temporary filter; the previous profile is restored automatically.
curl -s -X POST https://nftpars.app/api/v1/applications/$APP_ID/filters/temporary \
-H "Authorization: Bearer $NFTPARS_KEY" -H "Content-Type: application/json" \
-d '{"criteria": {"country": "RU", "gender": "female", "unknown": {"country": "exclude", "gender": "exclude"}},
"duration_minutes": 120}'
# How many indexed owners actually have reliable (self-declared, consented) attributes?
curl -s "https://nftpars.app/api/v1/filters/coverage?country=RU&gender=female" -H "Authorization: Bearer $NFTPARS_KEY"
Вебхуки
Події: gift.discovered, gift.owner_changed, market.listing_created, market.listing_updated (зміни ціни), market.listing_removed, market.sale, collection.updated, job.completed, job.failed. Лише HTTPS. Кожна доставка підписана — X-NFTPARS-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, "t.body")> — із повторними спробами й експоненційною затримкою. Після вичерпання спроб доставка позначається як невдала в журналі. Відхиляйте підписи, старші за 5 хвилин, і усувайте дублікати за X-NFTPARS-Delivery.
Python
import hmac, hashlib, time
def verify(secret: str, raw_body: bytes, header: str, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
ts = int(parts["t"])
if abs(time.time() - ts) > tolerance: # replay protection
return False
expected = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts["v1"])
# Then de-duplicate on the X-NFTPARS-Delivery header (stable across retries).
Протокол Pusher v7 за адресою wss://nftpars.app/app/<key>. Спершу налаштуйте канали (у кабінеті або через POST /ws/subscriptions): gift:<slug>, collection:<slug>, market:<collection>, offers (з урахуванням фільтрів) та jobs. Приватні канали авторизуються через POST /ws/auth з вашого сервера з ключем API. Кількість з’єднань, розмір повідомлень і частота обмежені; клієнти не можуть публікувати події.
import Pusher from "pusher-js";
// 1) GET https://nftpars.app/api/v1/ws/config for host/key, 2) add channels via POST https://nftpars.app/api/v1/ws/subscriptions
const pusher = new Pusher(APP_KEY, {
wsHost: "nftpars.app", wsPort: 443, forceTLS: true, enabledTransports: ["ws", "wss"], cluster: "",
channelAuthorization: {
endpoint: "https://nftpars.app/api/v1/ws/auth",
headers: { Authorization: `Bearer ${KEY}` }, // server-side only — never ship keys to browsers
},
});
pusher.subscribe("private-market.PlushPepe").bind("nftpars.event", (event) => console.log(event.type, event.data));
pusher.subscribe(`private-application.${APP_ID}.offers`).bind("nftpars.event", console.log); // filtered offer stream
Довідник endpoints
GET/statusПублічний стан сервісів (без авторизації та списання)
Публічний стан сервісів (без авторизації та списання)
Автентифікація не потрібна.
GET/pricingЧинні ціни операцій для цього застосунку (без списання)
Чинні ціни операцій для цього застосунку (без списання)
GET/gifts/{slug}
Параметр
Де
Опис
slug*
path
refresh
query
true — запитати нове спостереження. Якщо кеш недостатньо свіжий, повертається завдання з кодом 202.
max_age
query
У секундах; старіші дані вважаються STALE.
Idempotency-Key
header
GET/gifts/{slug}/owner
Параметр
Де
Опис
slug*
path
refresh
query
true — запитати нове спостереження. Якщо кеш недостатньо свіжий, повертається завдання з кодом 202.
max_age
query
У секундах; старіші дані вважаються STALE.
Idempotency-Key
header
GET/gifts/{slug}/history
Параметр
Де
Опис
slug*
path
cursor
query
limit
query
POST/gifts/batch
Параметр
Де
Опис
Idempotency-Key
header
GET/collections
Параметр
Де
Опис
cursor
query
limit
query
GET/collections/{collection_slug}
Параметр
Де
Опис
collection_slug*
path
GET/search
Фільтри застосунку (постійний профіль та активне тимчасове перевизначення) застосовуються автоматично.
Параметр
Де
Опис
q
query
collection
query
model
query
backdrop
query
symbol
query
owner_status
query
cursor
query
limit
query
GET/owners/{telegram_id}/gifts
Параметр
Де
Опис
telegram_id*
path
include_historical
query
cursor
query
limit
query
GET/wallets/{address}/gifts
Параметр
Де
Опис
address*
path
cursor
query
limit
query
GET/market/listings
Параметр
Де
Опис
collection
query
gift_slug
query
marketplace
query
status
query
price_min_nano
query
price_max_nano
query
sort
query
cursor
query
limit
query
GET/jobs/{job_id}
Параметр
Де
Опис
job_id*
path
GET/applications/{id}/usage
Параметр
Де
Опис
id*
path
from
query
to
query
GET/applications/{id}/filters
Параметр
Де
Опис
id*
path
PUT/applications/{id}/filters
Параметр
Де
Опис
id*
path
POST/applications/{id}/filters/temporaryТимчасовий фільтр, наприклад { "country": "RU", "gender": "female", "duration_minutes": 120 }, або (1.1) { "profile_id": "...", "duration_minutes": 60 }, або { "criteria": FilterCriteria, ... }. Попередня конфігурація відновлюється після завершення терміну.
Тимчасовий фільтр, наприклад { "country": "RU", "gender": "female", "duration_minutes": 120 }, або (1.1) { "profile_id": "...", "duration_minutes": 60 }, або { "criteria": FilterCriteria, ... }. Попередня конфігурація відновлюється після завершення терміну.