igsub.me Free API
100% free — no fees, no paid plans, no API key, no credit card. Free for everyone, forever.
A 100% free (no fees, no paid plans, no API key), public, browser-only JSON API for growing YouTube channels (subscribers, likes, comments, comment likes) and, when enabled, Instagram / TikTok / X / Facebook posts. There is no API key: your web page calls the API directly with fetch() (CORS), the visitor signs in with their own Google account, and every order spends that visitor's free credits. It is the same API our Blogger theme and our own sites use, so you can build a complete site with it: home page with order form, channel page, video page, order tracking page and account page. Every order is protected by hCaptcha.
https://igsub.me directly.Last updated 2026-10-25. Base URL https://igsub.me.
Quick start
Copy this into any page (inside <script type="module">). It signs the visitor in, reads the balance, finds a channel, passes hCaptcha, sends 100 subscribers and tracks the order.
// igsub.me public API — minimal client (no key, browser only)
const API = 'https://igsub.me';
const MY_REF = 'YOURCODE'; // your invite code: +1000 credits for every new user who signs in here
let token = localStorage.getItem('fs_token') || '';
async function api(path, { body, headers = {} } = {}) {
const h = { 'X-FS-Mode': 'token', ...headers };
if (body) h['Content-Type'] = 'application/json';
if (token) h['Authorization'] = 'Bearer ' + token;
const r = await fetch(API + path, {
method: body ? 'POST' : 'GET',
headers: h,
body: body ? JSON.stringify(body) : undefined,
mode: 'cors',
credentials: 'omit',
});
const data = await r.json().catch(() => ({}));
if (r.status === 401 && (data.kod === 'oturum_yok' || data.kod === 'kullanici_yok')) {
token = ''; localStorage.removeItem('fs_token'); // expired -> sign in again
}
return { ok: r.ok, status: r.status, data };
}
// 1) hCaptcha — solved inside an igsub.me frame (no keys on your site)
function captcha() {
return new Promise(resolve => {
const box = document.createElement('div');
box.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.5);display:grid;place-items:center;z-index:9999';
box.innerHTML = '<iframe src="' + API + '/captcha/frame.html" style="width:400px;max-width:95vw;height:560px;border:0;border-radius:12px;background:#fff"></iframe>';
document.body.appendChild(box);
function onMsg(e) {
if (e.origin !== API || !e.data || !e.data.fsCaptcha) return;
window.removeEventListener('message', onMsg); box.remove(); resolve(e.data.fsCaptcha);
}
window.addEventListener('message', onMsg);
box.onclick = e => { if (e.target === box) { window.removeEventListener('message', onMsg); box.remove(); resolve(''); } };
});
}
// 2) Sign in with Google (YouTube TV code)
async function signIn(onCode) {
const ref = new URLSearchParams(location.search).get('ref') || MY_REF;
const s = await api('/api/auth/device/start' + (ref ? '?ref=' + encodeURIComponent(ref) : ''), { body: {} }); // no captcha for sign-in
if (!s.ok) throw new Error(s.data.error);
onCode(s.data.user_code, s.data.qr_url, s.data.qr_image); // show code + link/QR
const until = Date.now() + s.data.expires_in * 1000;
while (Date.now() < until) {
await new Promise(r => setTimeout(r, Math.max(3, s.data.interval) * 1000));
const p = await api('/api/auth/device/poll', { headers: { 'X-FS-Device': s.data.device_token } });
if (p.data.status) { token = p.data.session_token; localStorage.setItem('fs_token', token); return; }
if (['expired', 'no_flow', 'only gmail'].includes(p.data.message)) throw new Error(p.data.message);
}
throw new Error('expired');
}
// 3) Balance
const { data: { kredi } } = await api('/api/kredi'); // kredi.kredi = credits
// 4) Find a channel and order 100 subscribers
const ch = await api('/api/resolve', { body: { q: 'https://www.youtube.com/@channel' } });
const captcha_token = await captcha();
const order = await api('/api/order', { body: { tip: 'sub', hedef_kanal: ch.data.channel_id, adet: 100, captcha_token } });
if (!order.ok) console.log(order.data.kod, order.data.error); // e.g. kredi_yok
// 5) Track it
const timer = setInterval(async () => {
const o = (await api('/api/order/' + order.data.order_id)).data;
console.log(o.status, o.biten_sayac + '/' + o.adet);
if (['completed', 'canceled', 'failed'].includes(o.status)) clearInterval(timer);
}, 10000);Rules & headers
- Base URL is always https://igsub.me — every request goes there. All responses are JSON (UTF-8).
- Send the header X-FS-Mode: token on every request and never send cookies (credentials: "omit").
- Without sign-in a visitor can find a channel/video and send 100 free YouTube subscribers once per channel (hCaptcha required). Everything else — likes, comments, other platforms, larger quantities, account, credits, history — requires Google sign-in.
- After sign-in send Authorization: Bearer <session_token> on every request. The token is valid 30 days.
- Browser only: requests must come from a real web page (the browser sends Origin, Sec-Fetch-Mode: cors and an OPTIONS preflight). Server-side calls (PHP, cURL, Python, Node, bots) get 403 browser_required.
- Use POST with Content-Type: application/json for request bodies; unknown body fields are rejected.
- hCaptcha is required for every order (body field captcha_token) and for invite codes and channel credits (header X-FS-Captcha). Sign-in has no captcha. You need no captcha key: show https://igsub.me/captcha/frame.html in an iframe (it opens in the visitor's browser language; add ?hl=xx to force one), the visitor solves it there, and you receive the token via postMessage. One token = one call. Never put any secret in your page; none is needed.
- Errors are { "kod": "<code>", "error": "<English message>", "hata": "<same>" } with a matching HTTP status. Translate on your side by kod.
- The Accept-Language header (sent automatically by browsers) selects the language of YouTube titles/descriptions where available.
- Accounts and credits are shared: a user who signs in on your site has the same account and balance as on igsub.me.
| Header | When | Value |
|---|---|---|
X-FS-Mode | every request | token |
Authorization | after sign-in | Bearer <session_token> |
Content-Type | POST with a body | application/json |
X-FS-Device | only /api/auth/device/poll | <device_token> |
X-FS-Captcha | POST /api/referans/uygula, /api/kredi/kanal-topla | <hCaptcha token> |
fetch options: mode: 'cors', credentials: 'omit'. Origin, User-Agent, Accept-Language and Sec-Fetch-* are added by the browser automatically — do not try to set them.
Sign-in flow
Sign-in uses the YouTube TV device code: the visitor opens youtube.com/qr/activate (or scans a QR code with their phone), signs in with Google and approves. Your page never sees a password.
Visitor Your page (browser) https://igsub.me
| click "Sign in" | |
|------------------>| POST /api/auth/device/start (no captcha)|
| |---------------------------------------->|
| |<-- user_code, qr_url, device_token -----|
|<-- show code -----| |
| opens youtube.com/qr/activate, approves with Google |
| | GET /api/auth/device/poll (every 5s) |
| | X-FS-Device: device_token |
| |---------------------------------------->|
| |<-- { status: true, session_token } -----|
| | save token -> Authorization: Bearer ... |
| paste channel | POST /api/resolve { q } |
| |<-- channel_id, videos ------------------|
| solves hCaptcha | iframe igsub.me/captcha/frame.html |
| |<-- postMessage { fsCaptcha: token } ----|
| click "Send" | POST /api/order { tip, hedef_kanal, adet, captcha_token }
| |<-- order_id, status: queued ------------|
| | GET /api/order/{order_id} (every 10s) |
| |<-- status, biten_sayac / adet ----------|POST /api/auth/device/start(no captcha; optionally?ref=INVITECODE) → showuser_code, a button toqr_urland theqr_image.- Every
intervalseconds:GET /api/auth/device/pollwith headerX-FS-Device: device_token. - When
statusis true, savesession_token(e.g. localStorage) and send it asAuthorization: Bearer. - On next visits call
GET /api/auth/me; a 401 means the token expired — delete it.
Free 100 subscribers (no sign-in)
- Any visitor can send 100 free YouTube subscribers without signing in — no account, no credits, no API key.
- Step 1: POST /api/resolve { "q": "<channel link, @handle or name>" } → channel_id (no Authorization header needed).
- Step 2: show the hCaptcha frame (https://igsub.me/captcha/frame.html) and wait for the token.
- Step 3: POST /api/order { "tip": "sub", "hedef_kanal": "<channel_id>", "captcha_token": "<token>", "fingerprint": "<stable random id>" } → order_id. Quantity is always 100.
- Step 4: GET /api/order/{order_id} every 10 s to show live progress (no sign-in needed).
- Limits: once per channel (lifetime), 1 free order per hour per visitor (IP + fingerprint), 1 free order per hour per channel, and a shared hourly cap for all external sites. When a limit is hit the API answers 401 giris_gerekli or 429 kanal_cooldown — then offer Google sign-in (free credits, every service).
- Only tip "sub" works without sign-in; likes, comments, other platforms and quantities above 100 need sign-in.
// no Authorization header — anonymous visitor
const ch = await api('/api/resolve', { body: { q: 'https://youtube.com/@channel' } });
const captcha_token = await captcha(); // igsub.me hCaptcha frame
let fp = localStorage.getItem('fs_fp');
if (!fp) { fp = crypto.randomUUID(); localStorage.setItem('fs_fp', fp); }
const o = await api('/api/order', { body: { tip: 'sub', hedef_kanal: ch.data.channel_id, captcha_token, fingerprint: fp } });
// o.data.order_id -> GET /api/order/{order_id}; on 401 giris_gerekli / 429 kanal_cooldown offer Google sign-inCredits
- Without sign-in: 100 free YouTube subscribers once per channel (max 1 free order per hour per visitor). No credits needed.
- Credits are free. They are not money and cannot be bought or withdrawn.
- Every signed-in user gets free credits every hour (gunluk_hak, normally 1000) plus a welcome bonus on the first sign-in.
- Each friend who signs in with the user's invite link/code gives +1000 credits. Invite link: https://igsub.me/?ref=<referans_kod> (or pass ref to /api/auth/device/start on your own site).
- Each extra YouTube channel on the user's Google account adds +1000 credits per hour (POST /api/kredi/kanal-topla once per hour).
- An order costs adet × kredi_carpani credits. If dispatch fails, credits are refunded automatically (iade).
- Some services unlock only after a number of invites (min_referans).
Earn credits with your site
Your site can earn free credits for you: add your own invite code and every new user who signs in there counts as your invite.
- Put your own invite code on your site and earn +1000 credits for every new user who signs in there.
- Get your code: sign in on igsub.me (or on your own site) and read referans_kod from GET /api/kredi — it is also shown on the account page.
- Send it with every sign-in (no captcha needed): POST /api/auth/device/start?ref=YOURCODE. In the example page just set window.FS_REF = 'YOURCODE'.
- If a visitor arrives with someone else's invite link (?ref=…), that link wins; otherwise your code is used.
- A user can be invited only once (first invite counts). Limits against abuse: max 30 credited sign-ins per code per day and max 2 per network (IP) per day.
- Spend the credits like any user: orders for your own channels on any of our sites. Credits are free and cannot be sold or withdrawn.
- Your visitors also get their own invite code and link (https://igsub.me/?ref=THEIRCODE) to earn credits themselves.
// sign-in on your site, credited to you POST https://igsub.me/api/auth/device/start?ref=YOURCODE X-FS-Mode: token // example page (starter-kit.html) <script>window.FS_REF = 'YOURCODE';</script>
hCaptcha (required for orders, invites and credits — not for sign-in)
Every POST /api/order needs a fresh captcha_token in the body, and POST /api/referans/uygula and POST /api/kredi/kanal-topla need one in the X-FS-Captcha header. Sign-in (POST /api/auth/device/start) has no captcha. Our hCaptcha site key works only on igsub.me, so the check runs inside a small igsub.me page that you show in an iframe. You never need a captcha key or secret.
- When the visitor clicks “Send”, open a modal with
<iframe src="https://igsub.me/captcha/frame.html">. It opens in the visitor's own browser language automatically; add?hl=tr(any language code) to force one andtheme=darkfor dark mode. Give it about 400×560 px so the challenge fits. - Listen for
messageevents from originhttps://igsub.me. When the visitor passes, you receive{ fsCaptcha: "<token>" }({ fsCaptchaExpired: true }if it expired before use). - Close the modal and send the token:
captcha_tokeninPOST /api/order, or headerX-FS-Captchafor invite / credit calls. A token works once; get a new one for each call. - On
captcha_yok/captcha_retshow the check again.
| Parameter | Description |
|---|---|
hl | Language of the check. Default (omitted or "auto"): the visitor's browser language, so nobody is forced into English. Force one with an hCaptcha language code: en, tr, es, pt, pt-BR, fr, de, it, nl, pl, ru, uk, ar, fa, hi, id, ms, th, vi, ja, ko, zh-CN, zh-TW, ro, cs, el, he, hu, sv, da, fi, no, bg, sr, hr, sk, sl, lt, lv, et and more. Unknown codes fall back to English. |
theme | "dark" for a dark check that matches dark mode; default light. |
<!-- auto language (visitor's browser) --> <iframe src="https://igsub.me/captcha/frame.html"></iframe> <!-- forced Turkish, dark --> <iframe src="https://igsub.me/captcha/frame.html?hl=tr&theme=dark"></iframe>
window.addEventListener('message', (e) => {
if (e.origin !== 'https://igsub.me' || !e.data) return;
if (e.data.fsCaptcha) placeOrder(e.data.fsCaptcha); // -> POST /api/order { ..., captcha_token }
});Endpoints
21 endpoints in 6 groups. All paths are relative to https://igsub.me. 🔒 = sign-in required · ◐ = works without sign-in (free 100 subscribers flow) · — = public.
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /api/site | — | Site information |
| GET | /api/link-servisler | — | Service catalog |
| POST | /api/auth/device/start | — | Start Google sign-in |
| GET | /api/auth/device/poll | — | Poll sign-in |
| GET | /api/auth/me | 🔒 | Current user |
| POST | /api/auth/logout | — | Sign out |
| GET | /api/kredi | 🔒 | Credit balance |
| GET | /api/kredi/hareketler | 🔒 | Credit history |
| POST | /api/referans/uygula | 🔒 | Apply an invite code |
| POST | /api/kredi/kanal-topla | 🔒 | Claim extra-channel credits |
| POST | /api/resolve | ◐ | Find a channel or video |
| GET | /api/search | 🔒 | Search channels |
| GET | /api/channel/{channelId} | ◐ | Channel page data |
| GET | /api/channel/{channelId}/videos | ◐ | More channel videos / shorts |
| GET | /api/video/{videoId} | ◐ | Video page data |
| POST | /api/order | ◐ | Create an order |
| GET | /api/order/{order_id} | ◐ | Order progress |
| GET | /api/order/{order_id}/events | ◐ | Order timeline |
| GET | /api/siparislerim | 🔒 | My orders |
| GET | /api/siparislerim/{id} | 🔒 | One of my orders |
| GET | /api/son-siparisler | — | Recent deliveries |
Site & catalog
Public information. No sign-in needed.
Site information
Name, languages and public settings of the API host. Call it once on page load if you want to show the brand or language list.
| Name | Type | Description |
|---|---|---|
domain | string | API host domain. |
ad | string | Brand name. |
varsayilan_dil | string | Default language code. |
diller | string[] | Supported language codes. |
secili_dil | string | Language picked for this request (Accept-Language). |
telegram_kanal | string | Telegram channel link. |
telegram_bot | string | Telegram bot link. |
{
"domain": "igsub.me",
"ad": "iGSub",
"varsayilan_dil": "en",
"diller": ["en", "tr", "es", "pt", "ar", "fr", "de", "ru"],
"secili_dil": "en",
"telegram_kanal": "https://t.me/...",
"telegram_bot": "https://t.me/..."
}ℹ️ Other fields (analytics ids, verification tags) belong to igsub.me itself — ignore them.
Service catalog
Every service with its limits and credit price. Use it to build the service picker, quantity limits and the cost preview. Hide services where aktif is false.
| Name | Type | Description |
|---|---|---|
servisler[] | Service[] | See the Service model. |
{
"servisler": [
{ "tip": "sub", "platform": "youtube", "tur": "sub", "min_adet": 10, "max_adet": 1000000, "kredi_carpani": 1, "min_referans": 0, "aktif": true, "sira": 0 },
{ "tip": "like", "platform": "youtube", "tur": "like", "min_adet": 10, "max_adet": 1000000, "kredi_carpani": 50, "min_referans": 3, "aktif": true, "sira": 6 },
{ "tip": "comment", "platform": "youtube", "tur": "comment", "min_adet": 1, "max_adet": 1000000, "kredi_carpani": 10, "min_referans": 100, "aktif": true, "sira": 7 },
{ "tip": "comment_like", "platform": "youtube", "tur": "comment_like", "min_adet": 10, "max_adet": 1000000, "kredi_carpani": 15, "min_referans": 5, "aktif": true, "sira": 8 },
{ "tip": "ig_views", "platform": "instagram", "tur": "views", "min_adet": 100, "max_adet": 2147483647, "kredi_carpani": 3, "min_referans": 0, "aktif": false, "sira": 1 }
]
}ℹ️ cost in credits = quantity × kredi_carpani.
ℹ️ min_referans > 0 means the user needs that many invited friends before using the service (error referans_gerekli).
Authentication
Google sign-in with the YouTube TV device code flow. Produces the session token used everywhere else.
Start Google sign-in
Creates a one-time code. Show user_code to the user and send them to qr_url (opens youtube.com/qr/activate with the code pre-filled) or show qr_image to scan with a phone. Keep device_token in memory for polling.
Limit: 12 starts per IP per 10 minutes
| Name | Type | Description |
|---|---|---|
ref | string | Invite code. Use YOUR code to earn +1000 credits for every new user who signs in on your site (or the visitor's ?ref= link if present). Applied when the sign-in completes; max 30 per code per day. Example: AB12CD34 |
| Name | Type | Description |
|---|---|---|
X-FS-Moderequired | string | Must be "token" so device_token / session_token are returned in JSON (no cookies). Example: token |
POST https://igsub.me/api/auth/device/start
{}| Name | Type | Description |
|---|---|---|
user_code | string | Code the user enters (format XXX-XXX-XXX). |
qr_url | string | https://youtube.com/qr/activate/<code> — open in a new tab. |
qr_image | string | PNG QR image URL of qr_url. |
verification_url | string | Plain activation page (code typed manually). |
interval | integer | Seconds to wait between polls (use at least 3). |
expires_in | integer | Seconds until the code expires. |
device_token | string | Opaque flow token; send it as X-FS-Device when polling. |
{
"ok": true,
"user_code": "ABC-DEF-GHI",
"qr_url": "https://youtube.com/qr/activate/ABC-DEF-GHI",
"qr_image": "https://api.qrserver.com/v1/create-qr-code/?size=280x280&data=...",
"verification_url": "https://www.google.com/device",
"interval": 5,
"expires_in": 1800,
"device_token": "eyJ...signed"
}Errors: rate_limitdevice_hata
Poll sign-in
Call every `interval` seconds until status is true, then save session_token (localStorage) and send it as Authorization: Bearer on every call. Always answers HTTP 200; read status/message.
| Name | Type | Description |
|---|---|---|
X-FS-Moderequired | string | "token" Example: token |
X-FS-Devicerequired | string | device_token from /api/auth/device/start. |
| Name | Type | Description |
|---|---|---|
status | boolean | true = signed in. |
session_token | string | Present when status is true. Valid for 30 days. |
message | string | When status is false: "not approved yet" (keep polling), "expired" / "no_flow" (start again), "only gmail" (only @gmail.com accounts), other values = temporary, keep polling. |
{ "status": false, "message": "not approved yet" }
{ "status": true, "redirect_url": "/account", "session_token": "eyJ1aWQiOjEy...signed" }ℹ️ New accounts receive a welcome credit bonus.
ℹ️ A user who already has an account gets the same account and credits (accounts are shared with igsub.me and the blog).
Current user
Validate the stored token on page load. 401 oturum_yok / kullanici_yok = token expired or deleted: clear it and show the sign-in button.
| Name | Type | Description |
|---|---|---|
kullanici.id | integer | User id. |
kullanici.email | string | Gmail address (show only to the user themself). |
kullanici.ad | string | Display name. |
kullanici.avatar | string | Avatar URL. |
kullanici.son_giris | string (date-time) | Last sign-in. |
{
"ok": true,
"kullanici": { "id": 156, "email": "[email protected]", "ad": "Name", "avatar": "https://lh3.googleusercontent.com/...", "son_giris": "2026-10-25T07:55:40Z" }
}Errors: oturum_yokkullanici_yok
Sign out
Tokens are stateless: signing out = deleting session_token from your storage. Calling this endpoint is optional.
POST https://igsub.me/api/auth/logout
{}| Name | Type | Description |
|---|---|---|
ok | boolean | Always true. |
{ "ok": true }Account & credits
The signed-in user, credit balance, credit history, invites and extra-channel credits.
Credit balance
Spendable credits and invite info. Show kredi in the header and refresh it after every order.
| Name | Type | Description |
|---|---|---|
kredi.kredi | integer | Spendable credits (1 credit = 1 unit × kredi_carpani). |
kredi.referans_kod | string | User's own invite code. Invite link: https://igsub.me/?ref=<code> |
kredi.davet_sayisi | integer | Friends invited so far (unlocks min_referans services). |
kredi.kanal_sayisi | integer | Extra YouTube channels found on the account (each adds hourly credits). |
kredi.gunluk_hak | integer | Free credits added every hour. |
kredi.sonraki_sifirlama | string (date-time) | When the next free credits arrive (UTC). |
{
"ok": true,
"kredi": { "kredi": 1000, "bonus_kredi": 0, "referans_kod": "8E6WNYMQ", "davet_sayisi": 0, "kanal_sayisi": 0, "gunluk_hak": 1000, "sonraki_sifirlama": "2026-10-25T08:00:00Z" }
}Errors: oturum_yok
Credit history
Credit movements, newest first.
| Name | Type | Description |
|---|---|---|
limit | integer | Default 50. Example: 30 |
offset | integer | Pagination offset. Example: 0 |
| Name | Type | Description |
|---|---|---|
hareketler[] | CreditTx[] | See the CreditTx model. |
{
"ok": true,
"hareketler": [
{ "id": 991, "tur": "siparis", "miktar": -100, "aciklama": "tip=sub adet=100x1", "order_id": 3927, "olusturma": "2026-10-24T18:05:43Z" },
{ "id": 990, "tur": "saatlik", "miktar": 1000, "aciklama": "hourly", "olusturma": "2026-10-24T18:00:00Z" }
]
}Errors: oturum_yok
Apply an invite code
Manually apply a friend's invite code (the inviter gets +1000 credits). Usually not needed: pass ?ref= to device/start instead.
| Name | Type | Description |
|---|---|---|
X-FS-Captcharequired | string | hCaptcha token from the igsub.me captcha frame (one token per call). |
| Name | Type | Description |
|---|---|---|
kodrequired | string | Invite code. Example: AB12CD34 |
POST https://igsub.me/api/referans/uygula
{ "kod": "AB12CD34" }| Name | Type | Description |
|---|---|---|
ok | boolean | true on success. |
bonus | integer | Credits given to the inviter. |
{ "ok": true, "veren_id": 12, "bonus": 1000 }Errors: captcha_yokcaptcha_retkod_yokreferans_gecersizreferans_kendireferans_varreferans_limit
Claim extra-channel credits
Counts the extra YouTube channels on the user's Google account; every channel adds +1000 credits per hour. Once per hour (when called earlier you get beklemede=true and kalan_saniye).
| Name | Type | Description |
|---|---|---|
X-FS-Captcharequired | string | hCaptcha token from the igsub.me captcha frame (one token per call). |
POST https://igsub.me/api/kredi/kanal-topla
{}| Name | Type | Description |
|---|---|---|
kanal_sayisi | integer | Extra channels found. |
saatlik_kazanc | integer | Credits per hour from channels. |
kredi | integer | New balance. |
beklemede | boolean | true = called too early. |
kalan_saniye | integer | Seconds until it can be called again. |
{ "ok": true, "kanal_sayisi": 3, "saatlik_kazanc": 3000, "kredi": 4000 }
{ "ok": true, "kanal_sayisi": 3, "saatlik_kazanc": 3000, "beklemede": true, "kalan_saniye": 2710 }YouTube lookup
Find channels and videos from any link, @handle or name. Needed to get the channel_id / video_id that orders use.
Find a channel or video
Accepts anything a user may paste: channel URL, @handle, /c/ or /user/ URL, channel name, video URL (watch, youtu.be, shorts) or a bare video id. Returns a channel (tip = "kanal") with its latest videos and similar channels, or a video (tip = "video").
Limit: 40 per minute per IP
| Name | Type | Description |
|---|---|---|
qrequired | string | User input. Example: https://www.youtube.com/@MrBeast |
POST https://igsub.me/api/resolve
{ "q": "https://www.youtube.com/@MrBeast" }| Name | Type | Description |
|---|---|---|
tip | "kanal" | "video" | What was found. |
channel_id | string | UC… id — use as hedef_kanal in orders. |
ad | string | Channel name. |
handle | string | Handle without @ (channel only, may be empty). |
avatar | string | Channel avatar (channel only). |
abone_sayi | integer | Subscriber count (channel only). |
video_sayi | integer | Video count (channel only). |
aciklama | string | Channel description (channel only). |
videolar[] | {id, baslik, kapak, bilgi}[] | Latest videos (channel only). id = video id. |
alternatifler[] | {channel_id, ad, avatar, abone_sayi}[] | Similar channels when the input was a name/handle — show "Not this channel?". |
video_id | string | Video id (video only). |
video | object | Video only: {id, baslik, aciklama, kapak, goruntulenme, sure_sn, yazar}. |
{
"tip": "kanal",
"channel_id": "UCX6OQ3DkcsbYNE6H8uQQuVA",
"ad": "MrBeast",
"handle": "mrbeast",
"avatar": "https://yt3.ggpht.com/...",
"abone_sayi": 523000000,
"video_sayi": 900,
"aciklama": "...",
"yontem": "handle",
"videolar": [ { "id": "dQw4w9WgXcQ", "baslik": "Video title", "kapak": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg", "bilgi": "12M views" } ],
"alternatifler": [ { "channel_id": "UC...", "ad": "MrBeast Gaming", "avatar": "...", "abone_sayi": 45000000 } ]
}
{
"tip": "video",
"video_id": "dQw4w9WgXcQ",
"channel_id": "UCuAXFkgsw1L7xaCfnd5JJOw",
"ad": "Channel name",
"video": { "id": "dQw4w9WgXcQ", "baslik": "Title", "aciklama": "...", "kapak": "...", "goruntulenme": 1500000000, "sure_sn": 213, "yazar": "Channel name" }
}Search channels
Channel search by name (max 12). Use for an autocomplete or a "pick your channel" list.
| Name | Type | Description |
|---|---|---|
qrequired | string | Search text. Example: cooking |
| Name | Type | Description |
|---|---|---|
kanallar[] | {channel_id, ad, avatar, abone_sayi}[] | Matching channels. |
{ "kanallar": [ { "channel_id": "UC...", "ad": "Cooking Channel", "avatar": "https://...", "abone_sayi": 120000 } ] }Errors: bos_girdigiris_gerekli
Channel page data
Full channel card plus the first 30 videos. Use it for a channel page (e.g. #/channel/UC...).
| Name | Type | Description |
|---|---|---|
channelIdrequired | string | UC… channel id. Example: UCX6OQ3DkcsbYNE6H8uQQuVA |
| Name | Type | Description |
|---|---|---|
kanal | Channel | See the Channel model. |
videolar[] | Video[] | See the Video model. |
{
"kanal": { "channel_id": "UCX6OQ3DkcsbYNE6H8uQQuVA", "handle": "mrbeast", "ad": "MrBeast", "aciklama": "...", "avatar": "...", "banner": "", "abone_sayi": 523000000, "video_sayi": 900, "ulke": "", "kategori": "" },
"videolar": [ { "video_id": "...", "channel_id": "UC...", "baslik": "...", "kapak": "...", "goruntulenme": 1000000, "sure_sn": 900, "sira": 1 } ]
}More channel videos / shorts
Paginated videos. Default tab uses limit/offset. For Shorts or live streams pass sekme=shorts|streams and page with the returned devam token (continuation).
| Name | Type | Description |
|---|---|---|
channelIdrequired | string | UC… channel id. |
| Name | Type | Description |
|---|---|---|
limit | integer | 1–100, default 30 (videos tab). Example: 30 |
offset | integer | Offset (videos tab). Example: 30 |
sekme | "videos" | "shorts" | "streams" | Tab. Default videos. Example: shorts |
continuation | string | Next-page token (devam) for shorts/streams. |
| Name | Type | Description |
|---|---|---|
videolar[] | Video[] | Videos (shorts/streams return {video_id, channel_id, baslik, kapak}). |
devam | string | Next page token for shorts/streams ("" = end). |
{ "channel_id": "UC...", "limit": 30, "offset": 30, "videolar": [ ... ] }
{ "channel_id": "UC...", "sekme": "shorts", "videolar": [ { "video_id": "...", "baslik": "...", "kapak": "..." } ], "devam": "4qmFsgK..." }Video page data
Video details plus its channel card. Use it for a video page with like/comment ordering.
| Name | Type | Description |
|---|---|---|
videoIdrequired | string | 11-character video id. Example: dQw4w9WgXcQ |
| Name | Type | Description |
|---|---|---|
video | object | {video_id, baslik, aciklama, channel_id, kapak, goruntulenme, sure_sn, etiketler[], yazar} |
kanal | Channel | {channel_id, ad} | Channel of the video. |
{
"video": { "video_id": "dQw4w9WgXcQ", "baslik": "Title", "aciklama": "...", "channel_id": "UC...", "kapak": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg", "goruntulenme": 1500000000, "sure_sn": 213, "etiketler": ["music"], "yazar": "Channel" },
"kanal": { "channel_id": "UC...", "ad": "Channel", "avatar": "...", "abone_sayi": 4000000 }
}Orders
Create orders, follow live progress and list the user's history.
Create an order
Without sign-in: 100 free YouTube subscribers (tip sub only) once per channel, max 1 free order per hour per visitor, hCaptcha required. Signed in: spends credits (quantity × kredi_carpani) and starts delivery immediately. YouTube services need hedef_kanal (channel_id from /api/resolve); like and comment also need hedef_video. Instagram / TikTok / X / Facebook services need the full post URL in hedef_video and no hedef_kanal.
Limit: 30 orders per hour per user (external sites) · 20 per hour per IP
| Name | Type | Description |
|---|---|---|
tiprequired | string | Service type from /api/link-servisler: sub, like, comment, comment_like (YouTube) · ig_views, ig_likes, tiktok_views, x_views, fb_likes (only when aktif). Example: sub |
hedef_kanal | string | YouTube channel_id (UC…). Required for YouTube services. Example: UCX6OQ3DkcsbYNE6H8uQQuVA |
hedef_video | string | YouTube video id (like, comment, comment_like) or full post URL (Instagram/TikTok/X/Facebook). Example: dQw4w9WgXcQ |
adet | integer | Quantity. Signed in: clamped to the service min/max and to what the balance can pay (omit = 100). Without sign-in: always 100 (omit it). Example: 100 |
captcha_tokenrequired | string | hCaptcha token, required for every order. Get it from the igsub.me captcha frame (see "hCaptcha" section): open https://igsub.me/captcha/frame.html in an iframe and read the token from the postMessage { fsCaptcha }. Single use. |
fingerprint | string | Stable device id (random string kept in localStorage). Recommended without sign-in: the free quota is counted per IP + fingerprint. |
POST https://igsub.me/api/order
{ "tip": "sub", "hedef_kanal": "UCX6OQ3DkcsbYNE6H8uQQuVA", "adet": 100, "captcha_token": "P1_eyJ0eXAi..." }
{ "tip": "like", "hedef_kanal": "UCX6OQ3DkcsbYNE6H8uQQuVA", "hedef_video": "dQw4w9WgXcQ", "adet": 50, "captcha_token": "P1_eyJ0eXAi..." }
{ "tip": "tiktok_views", "hedef_video": "https://www.tiktok.com/@user/video/7300000000000000000", "adet": 1000, "captcha_token": "P1_eyJ0eXAi..." }| Name | Type | Description |
|---|---|---|
order_id | string | Unguessable order token. Keep it: it is the key for tracking (share links like #/order/<order_id>). |
status | OrderStatus | Usually "queued"; "failed" if dispatch failed (credits refunded automatically). |
durum | string | Same status, internal name. |
adet | integer | Final quantity after clamping. |
{ "ok": true, "order_id": "c43a7ec92aef79f3e7f96c1b55125d44", "durum": "kuyrukta", "status": "queued", "adet": 100 }Errors: giris_gereklikanal_cooldowncaptcha_yokcaptcha_retgecersiz_tiphedef_yoklink_gecersizservis_yokkredi_yokmin_kredireferans_gereklirate_limitgecersiz_govde
ℹ️ Every order needs a fresh hCaptcha token (one token = one order).
ℹ️ Request body must contain only these fields (unknown fields → 400 gecersiz_govde).
ℹ️ Refresh /api/kredi after an order.
Order progress
Live progress, synced with the delivery engine on every call. Poll every 8–15 seconds while the status is not final. Progress = biten_sayac / adet.
| Name | Type | Description |
|---|---|---|
order_idrequired | string | Token from /api/order. |
| Name | Type | Description |
|---|---|---|
order_id | string | Order token. |
tip | string | Service type. |
status | OrderStatus | pending | queued | in_progress | completed | canceled | failed. |
adet | integer | Ordered quantity. |
baslangic_sayac | integer | Counter (subscribers/likes) when delivery started; 0 until known. |
biten_sayac | integer | Units delivered so far. |
hedef_kanal | string | Target channel. |
hedef_video | string | Target video / link. |
olusturma | string (date-time) | Created at. |
biten | string (date-time) | null | Finished at. |
{
"order_id": "c43a7ec92aef79f3e7f96c1b55125d44",
"tip": "sub",
"durum": "calisiyor",
"status": "in_progress",
"adet": 100,
"baslangic_sayac": 18300,
"biten_sayac": 40,
"hedef_kanal": "UCKtuGDfMjgNe5M9Eu_XsdRw",
"hedef_video": "",
"olusturma": "2026-10-24T18:05:43Z",
"biten": null
}Errors: siparis_yokgiris_gerekli
Order timeline
Step-by-step events for a timeline view.
| Name | Type | Description |
|---|---|---|
order_idrequired | string | Order token. |
| Name | Type | Description |
|---|---|---|
olaylar[] | OrderEvent[] | See the OrderEvent model. |
{
"order_id": "c43a7ec9...",
"olaylar": [
{ "id": 1, "olay": "olusturuldu", "detay": "tip=sub adet=100", "ts": "2026-10-24T18:05:43Z" },
{ "id": 2, "olay": "kuyruga_alindi", "detay": "ref=...", "ts": "2026-10-24T18:05:44Z" }
]
}Errors: siparis_yok
My orders
The signed-in user's orders on every site, newest first, with the latest event.
| Name | Type | Description |
|---|---|---|
limit | integer | Default 50. Example: 20 |
offset | integer | Pagination offset. Example: 0 |
| Name | Type | Description |
|---|---|---|
siparisler[] | OrderSummary[] | See the OrderSummary model. Link each row with public_token. |
{
"ok": true,
"siparisler": [
{ "id": 3927, "public_token": "c43a7ec9...", "platform": "youtube", "tip": "sub", "hedef_kanal": "UC...", "hedef_video": "", "adet": 1000, "durum": "tamamlandi", "status": "completed", "baslangic_sayac": 18300, "biten_sayac": 1000, "son_olay": "kuyruga_alindi", "olusturma": "2026-10-24T18:05:43Z", "biten": "2026-10-24T18:41:02Z" }
]
}Errors: oturum_yok
One of my orders
Summary plus full event list of one order owned by the user (numeric id from /api/siparislerim).
| Name | Type | Description |
|---|---|---|
idrequired | integer | Numeric order id. |
| Name | Type | Description |
|---|---|---|
siparis | OrderSummary | Order summary. |
olaylar[] | OrderEvent[] | Events. |
{ "ok": true, "siparis": { ... }, "olaylar": [ ... ] }Errors: gecersiz_idsiparis_yokoturum_yok
Social proof
Recent completed deliveries (masked names) for a live activity feed.
Recent deliveries
Latest completed orders across all sites for a "just delivered" ticker. Names are masked server-side; no e-mail, channel or IP is returned. Cached 30 seconds.
| Name | Type | Description |
|---|---|---|
siparisler[] | {tip, adet, ad, saniye_once}[] | ad = masked name ("" = guest), saniye_once = seconds ago. |
{ "siparisler": [ { "tip": "sub", "adet": 100, "ad": "Al***", "saniye_once": 42 }, { "tip": "like", "adet": 50, "ad": "", "saniye_once": 95 } ] }Data models
Service
Item of /api/link-servisler.
| Name | Type | Description |
|---|---|---|
tip | string | Service type used in orders. |
platform | string | youtube | instagram | tiktok | x | facebook |
tur | string | sub | like | comment | comment_like | views | likes |
min_adet | integer | Minimum quantity. |
max_adet | integer | Maximum quantity per order. |
kredi_carpani | integer | Credits per unit. |
min_referans | integer | Invites needed to unlock (0 = open). |
aktif | boolean | false = hide it. |
sira | integer | Display order. |
Channel
YouTube channel card.
| Name | Type | Description |
|---|---|---|
channel_id | string | UC… id. |
handle | string | Handle without @. |
ad | string | Name. |
aciklama | string | Description. |
avatar | string | Avatar URL. |
banner | string | Banner URL (may be empty). |
abone_sayi | integer | Subscribers. |
video_sayi | integer | Videos. |
Video
Video card in channel lists.
| Name | Type | Description |
|---|---|---|
video_id | string | Video id. |
channel_id | string | Channel id. |
baslik | string | Title. |
aciklama | string | Description. |
kapak | string | Thumbnail URL (fallback: https://i.ytimg.com/vi/<id>/mqdefault.jpg). |
goruntulenme | integer | Views. |
sure_sn | integer | Duration in seconds. |
etiketler | string[] | Tags. |
OrderSummary
Row of /api/siparislerim.
| Name | Type | Description |
|---|---|---|
id | integer | Numeric id (for /api/siparislerim/{id}). |
public_token | string | Order token (for /api/order/{order_id}). |
platform | string | Platform. |
tip | string | Service type. |
hedef_kanal | string | Target channel. |
hedef_video | string | Target video / link. |
adet | integer | Quantity. |
status | OrderStatus | English status. |
baslangic_sayac | integer | Start count. |
biten_sayac | integer | Delivered. |
son_olay | string | Latest event name. |
olusturma | string (date-time) | Created. |
biten | string (date-time) | Finished (omitted while running). |
OrderEvent
Timeline item.
| Name | Type | Description |
|---|---|---|
olay | string | olusturuldu (created) · kuyruga_alindi (queued for delivery) · teslimat_hata (dispatch error) · kredi_iade (credits refunded) · otomatik_sonlandir (closed automatically) |
detay | string | Free text detail. |
ts | string (date-time) | Time. |
CreditTx
Credit history row.
| Name | Type | Description |
|---|---|---|
tur | string | saatlik (hourly free credits) · hosgeldin (welcome bonus) · referans_bonus (invite bonus) · siparis (order, negative) · iade (refund) |
miktar | integer | + added / − spent. |
aciklama | string | Detail. |
order_id | integer | Related order (optional). |
olusturma | string (date-time) | Time. |
Order status
pending → queued → in_progress → completed. Final states: completed, canceled, failed. Responses also carry the internal name in durum.
| status | durum | Meaning |
|---|---|---|
pending | beklemede | Created, not yet sent to delivery. |
queued | kuyrukta | Accepted by the delivery engine, waiting to start. |
in_progress | calisiyor | Delivering. biten_sayac grows. |
completed | tamamlandi | Finished (final). |
canceled | iptal | Canceled (final). |
failed | hata | Could not be dispatched; credits refunded (final). |
Errors
Every error has an HTTP status and a body like { "kod": "kredi_yok", "error": "not enough credits", "hata": "not enough credits" }. Show your own text based on kod — this is how you translate the API into any language.
| kod | HTTP | Meaning | What to do |
|---|---|---|---|
giris_gerekli | 401 | Sign in required (or the free no-sign-in quota is used up for this channel/visitor). | Open the sign-in dialog: signed-in users order with credits. |
kanal_cooldown | 429 | This channel already received a free order in the last hour. | Sign in or try again later. |
oturum_yok | 401 | Token missing, invalid or expired. | Delete the token, ask to sign in again. |
kullanici_yok | 401 | Account no longer exists. | Delete the token. |
browser_required | 403 | Not a real browser request (server-side script). | Call the API from a web page. |
not_public | 403 | Endpoint not available to external sites. | Do not use it. |
captcha_yok | 400 | hCaptcha token missing (captcha_token in /api/order, X-FS-Captcha header for invite code / channel credits). | Show the hCaptcha frame and send its token. |
captcha_ret | 400 | hCaptcha token invalid, expired or already used. | Show the hCaptcha frame again. |
kredi_yok | 402 | Not enough credits. | Show the balance, invite link and next refill time. |
min_kredi | 402 | Balance below the service minimum. | Same as above. |
referans_gerekli | 403 | Service needs more invites ("x/y" in message). | Show the invite link. |
rate_limit | 429 | Too many requests. | Wait and retry with backoff. |
gecersiz_govde | 400 | Invalid JSON or unknown field. | Fix the request body. |
gecersiz_tip | 400 | Unknown service type. | Use a tip from /api/link-servisler. |
hedef_yok | 400 | hedef_kanal missing. | Resolve the channel first. |
link_gecersiz | 400 | Link does not match the platform. | Ask for a valid post URL. |
servis_yok | 400 | Service disabled. | Hide it. |
bos_girdi | 400 | Empty input. | Validate before sending. |
cozulemedi | 422 | Channel/video not found. | Ask for another link. |
kanal_yok | 404 | Channel not found. | — |
video_yok | 404 | Video not found. | — |
siparis_yok | 404 | Order not found. | — |
referans_gecersiz | 404 | Invite code not found. | — |
referans_kendi | 400 | Own invite code. | — |
referans_var | 409 | Invite already used. | — |
referans_limit | 429 | Invite limit for this network/account. | — |
kanal_alinamadi | 502 | Could not read the user's channels. | Ask to sign in again. |
device_hata | 502 | Sign-in could not start. | Retry. |
db_hata | 500 | Temporary server error. | Retry later. |
Rate limits & security
| Scope | Limit |
|---|---|
| All /api calls | 6 requests/second per IP (burst 60). Abusive IPs are banned automatically for 60 minutes. |
| Heavy calls (resolve, search, order, channel, video, device start) | 30 per minute per IP (burst 15). |
| Per user (external sites) | 90 requests per minute. |
| Orders per user (external sites) | 30 per hour, plus the credit balance. |
| Free orders without sign-in | 100 subscribers once per channel; 1 per hour per visitor (IP + fingerprint); 1 per hour per channel; shared hourly cap for all external sites. |
| Per site (Origin) | 1500 requests per minute. |
| Sign-in starts | 12 per IP per 10 minutes. |
| Resolve | 40 per minute per IP. |
- On
429 rate_limitwait a few seconds and retry with exponential backoff; do not loop. - Poll order progress every 8–15 seconds, never faster. Stop polling on final states.
- Cache
/api/link-servislerand/api/sitefor the page session. - Never ship secrets. The token belongs to the visitor; store it only in their browser.
- Server-side requests, headless browsers and bots are blocked; repeated abuse bans the IP automatically.
Build a full site
These are the exact pages of our Blogger theme. Use hash routes (#/channel/…) so it works on any static host, including Blogger.
Header (every page)
- On load: if a token is stored call GET /api/auth/me. 200 → show avatar + name; 401 → delete the token, show "Sign in with Google" (no captcha for sign-in).
- Show the balance from GET /api/kredi (kredi.kredi). Refresh it after each order.
- Optional: a search box that sends any link/@handle/name to your channel/video page.
Home page with order form
- GET /api/link-servisler → build service tabs from items with aktif = true (YouTube: sub, like, comment, comment_like; others when active).
- Input "channel or video link" → POST /api/resolve. tip = "kanal": show avatar, name, abone_sayi, videolar; tip = "video": show the video card.
- If alternatifler is not empty show "Not this channel?" with those channels.
- Quantity input limited by min_adet / max_adet; show cost = adet × kredi_carpani and the user's balance. Lock services where min_referans > davet_sayisi.
- Send → open the hCaptcha frame (https://igsub.me/captcha/frame.html in an iframe), wait for the postMessage token, then POST /api/order with captcha_token. On success go to the order page with order_id. On error show the message for kod (kredi_yok → invite link + next refill time, captcha_ret → show the check again).
- Optional live feed: GET /api/son-siparisler every 30 s ("Al*** received 100 subscribers 42 s ago").
Channel page (e.g. #/channel/UC…)
- GET /api/channel/{channelId} → channel header (avatar, banner, abone_sayi, video_sayi, aciklama) + first 30 videos.
- "Load more": GET /api/channel/{channelId}/videos?offset=30. Shorts tab: ?sekme=shorts then pass devam as continuation.
- Subscriber order form on top (tip sub, hedef_kanal = channelId); clicking a video opens the video page.
Video page (e.g. #/video/VIDEO_ID)
- GET /api/video/{videoId} → title, thumbnail or YouTube embed (https://www.youtube.com/embed/VIDEO_ID), views, duration, channel card.
- Order buttons for like, comment, comment_like (hedef_kanal = video.channel_id, hedef_video = video id) and sub.
Order tracking page (e.g. #/order/ORDER_ID)
- GET /api/order/{order_id} every 10 s → progress bar biten_sayac / adet, status badge, start count.
- GET /api/order/{order_id}/events → timeline. Stop polling when status is completed, canceled or failed.
- The order_id link can be shared; it only shows progress, never personal data.
Account page
- GET /api/kredi → balance, gunluk_hak, sonraki_sifirlama (countdown), referans_kod (invite link https://igsub.me/?ref=CODE + share buttons), davet_sayisi.
- Button "Claim channel credits" → hCaptcha frame → POST /api/kredi/kanal-topla with X-FS-Captcha (once per hour).
- Field "Have an invite code?" → hCaptcha frame → POST /api/referans/uygula with X-FS-Captcha.
- Tables: GET /api/siparislerim (orders, link to order page with public_token) and GET /api/kredi/hareketler (credit history).
- Sign out = delete the stored token.
Example page
Our Blogger theme as one HTML file — the same design and the same features: home page with service tabs and live deliveries, channel page with videos and Shorts, video page, order tracking with timeline, account page with credits, invites and history, Google sign-in, hCaptcha check, dark mode, header search and popular searches. Upload it as index.html anywhere and change “My Site” to your name. Built-in languages: English and Turkish (window.FS_DIL = 'tr'); all texts are inside the script.
FAQ
Is the API really free?
Yes. There are no fees, no paid plans and no usage billing — for you and for your visitors. Orders use free credits that refill every hour.
Can I earn credits with my site?
Yes. Pass your invite code to /api/auth/device/start?ref=YOURCODE (or set window.FS_REF in the example page). Every new user who signs in on your site gives you +1000 credits (max 30 per day).
Do I need an API key?
No. There are no keys. The visitor signs in with Google on your page and uses their own credits.
Can I call it from PHP / Node / Python / cURL?
No. Only real browsers are accepted (403 browser_required). Build your page in HTML + JavaScript; the visitor's browser calls the API.
Does it work on Blogger / WordPress / Wix / GitHub Pages?
Yes — anywhere you can add HTML and JavaScript. All calls go to https://igsub.me with CORS.
Can visitors order without signing in on my site?
Yes, but only the free 100 YouTube subscribers: once per channel, max 1 per hour per visitor, with hCaptcha. Likes, comments, other platforms and bigger orders need Google sign-in (free credits).
Is there a captcha?
Yes: every order, invite code and channel-credit claim needs hCaptcha (sign-in does not). It runs inside a small igsub.me frame (https://igsub.me/captcha/frame.html), so you need no captcha keys — you receive the token via postMessage and send it (captcha_token for orders, X-FS-Captcha header for the others).
Which Google accounts work?
@gmail.com accounts.
How long is a session valid?
30 days. On 401 oturum_yok ask the user to sign in again.
Is there an invite reward?
Yes: every friend who signs in with the user's invite code gives that user +1000 credits.
Which language are responses in?
Errors and status are English (kod is language-neutral). Translate your UI freely.
Is there a sandbox?
No. Use a test channel and small quantities; credits are free.
Where is the machine-readable spec?
OpenAPI 3.1: https://igsub.me/developers/openapi.json — plain text / Markdown for AI assistants: https://igsub.me/developers/llms.txt
Changelog
v1.2.0 2026-10-25
- Sign-in (POST /api/auth/device/start) no longer needs hCaptcha. hCaptcha stays required for orders, invite codes and channel credits.
- Admin statistics per external site (requests, sign-ins, orders).
v1.1.0 2026-10-25
- hCaptcha is required for every order (captcha_token) and for sign-in start, invite codes and channel credits (X-FS-Captcha header). Solved in the igsub.me frame https://igsub.me/captcha/frame.html — no keys needed.
- Site owners can pass their own invite code (?ref=CODE / window.FS_REF) and earn +1000 credits per new user who signs in on their site.
- The example page (starter-kit.html) is now identical to our Blogger theme.
- Cross-site API is served only from https://igsub.me.
- Free without sign-in: 100 YouTube subscribers once per channel (resolve, channel, video, order and tracking work without sign-in; hCaptcha required).
- The hCaptcha frame opens in the visitor's browser language by default (?hl=auto); ?hl=xx forces a language.
v1.0.0 2026-10-25
- First public release: no API key, browser-only CORS, Google sign-in, English errors (kod + error) and English order status.
For AI assistants
If you are an AI model helping someone build a site with this API: read /developers/llms.txt (full reference in Markdown) or import /developers/openapi.json (OpenAPI 3.1). Generate browser JavaScript only (fetch with X-FS-Mode: token and Authorization: Bearer), never server-side code, and never invent API keys.
Prefer the hosted tool? Use Instabayim1 directly.