API
Alles wat het paneel doet, is via twee afzonderlijke API's beschikbaar. Beide gebruiken hetzelfde account, hetzelfde saldo en dezelfde catalogus; ze verschillen in formaat en in wat ze kunnen.
Alles wat het paneel doet, is via twee afzonderlijke API's beschikbaar. Beide gebruiken hetzelfde account, hetzelfde saldo en dezelfde catalogus; ze verschillen in formaat en in wat ze kunnen.
Waarom twee API's?
De klassieke reseller-API (v2) die de hele branche gebruikt, stuurt een formulier naar één endpoint en antwoordt altijd met HTTP 200. Dat is precies het formaat dat kant-en-klare panelsoftware verwacht, dus het blijft ongewijzigd. Wie zijn eigen systeem schrijft, liep juist voortdurend tegen de grenzen ervan aan: fouten waren niet van elkaar te onderscheiden, de catalogus kwam in één stuk binnen en de status van een bestelling moest eindeloos worden opgevraagd. v3 is daarvoor geschreven.
Vergelijking
| Functie | Legacy (v2) | Nieuw (v3) |
|---|---|---|
| Formaat | Eén endpoint, formulierverzending, parameter action | Resourcegerichte REST, JSON-body |
| HTTP-statuscode | Altijd 200, ook bij een fout | Echte codes (400, 401, 402, 404, 409, 429, 502) |
| Fouten | Vrije tekst | type + vaste code + vertaald bericht + param + doc_url |
| Bestelstatus | Alleen vertaalde tekst | Vaste machinewaarde plus een apart weergavelabel |
| Dienstomschrijving | Niet aanwezig | Omschrijving in 10 talen, gemiddelde levertijd, platform, categorie |
| Bestelvelden | Afgeleid uit de naam van het type | Elke dienst publiceert zijn eigen veldschema |
| Prijseenheid | Niet vermeld (bron van fouten van factor 1000 bij pakketten) | Expliciet vermeld als per_1000 of per_order |
| Catalogus | Alle diensten in één antwoord | Filters plus paginering met cursor |
| Bescherming tegen dubbele bestellingen | Niet aanwezig | Idempotency-Key |
| Statusmelding | Voortdurend opvragen | Ondertekende webhooks of een gebeurtenisstroom |
| Schema | Niet aanwezig | OpenAPI 3.1 |
| Talen | Engels en Turks (aparte adressen) | 10 talen (via header of parameter) |
Welke moet ik kiezen?
Kies de legacy-API als je kant-en-klare panelsoftware, een bot of een resellerpaneel gebruikt. De meeste vragen je alleen het API-adres en de sleutel aan te passen, en werken binnen enkele minuten.
Kies v3 als je je eigen applicatie, webshop of automatisering schrijft. Foutafhandeling, bescherming tegen dubbele bestellingen en meldingen zitten er al in, en je kunt je bestelformulier rechtstreeks uit het dienstschema opbouwen.
Aan de slag
- 1Maak een API-sleutel aan op het tabblad Sleutels.
- 2Haal de dienstenlijst op en bekijk de id en het veldschema van de dienst die je nodig hebt.
- 3Controleer de bestelling eerst met preview en maak hem daarna pas aan.
- 4Registreer een webhook, of lees de gebeurtenisstroom, om statuswijzigingen te volgen.
Een REST-API die is ontworpen voor ontwikkelaars die hun eigen systeem bouwen: resourcegerichte paden, echte HTTP-statuscodes, machineleesbare fouten en ondertekende meldingen.
Basisadres
Alle paden worden achter dit adres geplakt. De versie zit in het pad: mocht er ooit een brekende wijziging nodig zijn, dan verschijnt er een nieuw pad (v4) en blijft dit pad ongewijzigd werken. De publicatiedatum van het contract komt bij elk antwoord terug in de header X-Api-Version.
https://panelfollows.com/api/v3Authenticatie
Stuur je API-sleutel als Bearer-token mee in de header Authorization. Als alternatief wordt ook de header X-Api-Key geaccepteerd.
GET https://panelfollows.com/api/v3/account
Authorization: Bearer pf_live_...Je bestaande legacy-sleutel werkt ook op v3, dus je kunt meteen aan de slag. Gebruik in productie een v3-sleutel: die kun je labelen, stuk voor stuk intrekken, en hij wordt nooit als platte tekst opgeslagen.
Snelle start
curl https://panelfollows.com/api/v3/services?limit=5 \
-H "Authorization: Bearer YOUR_API_KEY"Taal
De taal van het antwoord kies je met de header Accept-Language of met de parameter ?lang=; de parameter gaat boven de header. Dienstnamen, dienstomschrijvingen, categorienamen, het statuslabel van een bestelling, de labels van bestelvelden en foutmeldingen komen allemaal in die taal terug.
Machinewaarden veranderen in geen enkele taal: error.code, order.status, service.type en currency zijn altijd hetzelfde. Bouw je logica op die waarden en laat de tekst aan je gebruikers zien.
Accept-Language: tr
# veya
GET https://panelfollows.com/api/v3/services?lang=trFormaat van verzoek en antwoord
De body van een verzoek is JSON (application/json); voor snelle proefjes wordt ook form-urlencoded geaccepteerd. Antwoorden zijn JSON: een losse resource is een gewoon object, en lijsten komen in een envelop met data, has_more en next_cursor. Elk object bevat een veld object dat zijn type benoemt.
Bedragen komen terug als decimale TEKENREEKSEN ("1.2340"), niet als getallen met drijvende komma. Zet ze aan jouw kant om naar een decimaal type, zodat er geen centen verloren gaan. De valuta is USD.
Tijdstempels hebben het formaat RFC 3339 (2026-08-21T00:24:45.255Z).
Fouten
Bij een fout komt er een echte HTTP-statuscode terug en bevat de body één enkel error-object. Je code hoort te kijken naar error.code: die waarde ligt vast en verandert niet mee met de taal.
HTTP/1.1 400 Bad Request
Content-Type: application/json
X-Request-Id: req_0c858d8af7f65eca001b2f5a
{
"object": "error",
"error": {
"type": "invalid_request_error",
"code": "quantity_out_of_range",
"message": "Miktar, bu servisin izin verdiği aralığın dışında.",
"param": "quantity",
"doc_url": "https://panelfollows.com/api-docs#error-quantity_out_of_range",
"request_id": "req_0c858d8af7f65eca001b2f5a"
}
}| type | Brede klasse: valt het opnieuw te proberen of ligt de fout bij jou. |
| code | Vaste machinewaarde. Bouw je logica hierop. |
| message | Leesbare uitleg in de taal die je hebt gekozen. |
| param | Naam van het veld dat de fout veroorzaakte, als dat er is. |
| doc_url | Link naar het precieze onderdeel van deze documentatie. |
| request_id | De enige verwijzing die je meestuurt als je contact opneemt met support. |
Verzoeklimiet
600 verzoeken per minuut per sleutel, plus 900 per minuut per IP. Elk antwoord bevat RateLimit-Limit, RateLimit-Remaining en RateLimit-Reset, zodat je jezelf kunt afremmen voordat je tegen de limiet aan loopt. Ga je eroverheen, dan volgt 429 met een Retry-After-header.
Paginering
Lijsten worden gepagineerd met een cursor. Stuur limit voor de paginagrootte (maximaal 500) en starting_after met de id van het laatste item op de vorige pagina. Ga door tot has_more false is; next_cursor geeft je de cursor voor het volgende verzoek. Een limit buiten het bereik wordt niet stilletjes bijgeknipt maar geeft een fout: stil bijknippen laat een client geloven dat hij alles heeft opgehaald.
Bescherming tegen dubbele bestellingen (Idempotency-Key)
Voeg bij het aanmaken van een bestelling een willekeurige Idempotency-Key-header toe. Valt de verbinding weg en probeer je het opnieuw met dezelfde sleutel, dan komt er geen tweede bestelling: het antwoord van het eerste verzoek komt ongewijzigd terug, met de header Idempotent-Replay: true. Deze gegevens worden 24 uur bewaard.
Stuur je dezelfde sleutel met een ANDERE body, dan volgt 409 idempotency_key_reuse. Dat betekent bijna altijd dat het genereren van sleutels aan de clientkant stuk is. Een mislukt verzoek verbrandt de sleutel niet: los het probleem op en probeer het opnieuw met dezelfde sleutel.
Een bestelling aanmaken
curl -X POST https://panelfollows.com/api/v3/orders \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8f14e45f-ea3a-4b1c-9c1e-2b0d5c6a7e91" \
-d '{
"service": 1234,
"link": "https://instagram.com/username",
"quantity": 1000
}'Veldschema van een dienst
Elke dienst publiceert in de array fields welke velden hij bij een bestelling vraagt: veldnaam, type, of het verplicht is, de grenzen ervan en een label met omschrijving in de taal van de gebruiker. Staat determines_quantity van een veld op true, dan wordt de hoeveelheid berekend uit het aantal regels in dat veld.
// Servisin kendi alan şemasından formu OTOMATİK üretmek:
// hiçbir servis tipini koda gömmeniz gerekmez.
const res = await fetch("https://panelfollows.com/api/v3/services/1234", {
headers: { Authorization: "Bearer YOUR_API_KEY", "Accept-Language": "tr" },
});
const service = await res.json();
for (const field of service.fields) {
renderInput({
name: field.name,
label: field.label, // kullanıcının dilinde
hint: field.description, // kullanıcının dilinde
required: field.required,
type: field.type, // url | integer | string | text_lines
min: field.min,
max: field.max,
// true ise miktarı bu alanın satır sayısı belirler
countsLines: field.determines_quantity === true,
});
}Het dienstobject
{
"object": "service",
"id": 1234,
"name": "Instagram Takipçi | Türk | 30 gün telafi",
"description": "Gerçek hesaplardan Türk takipçi. Başlangıç 0-1 saat.",
"type": "default",
"platform": "instagram",
"category": { "slug": "instagram-takipci", "name": "Instagram Takipçi" },
"pricing": {
"rate": "1.2340",
"currency": "USD",
"unit": "per_1000",
"unit_note": "Fiyat 1000 adet içindir."
},
"limits": { "min": 100, "max": 100000 },
"features": { "refill": true, "cancel": false, "dripfeed": true },
"average_time_seconds": 4320,
"fields": [
{
"name": "link",
"type": "url",
"required": true,
"label": "Bağlantı",
"description": "Gönderimin yapılacağı profilin herkese açık adresi."
},
{
"name": "quantity",
"type": "integer",
"required": true,
"label": "Miktar",
"description": "Kaç adet gönderileceği.",
"min": 100,
"max": 100000
}
],
"is_active": true,
"updated_at": "2026-08-20T09:15:00.000Z"
}Bestelling vooraf bekijken (droge run)
POST /orders/preview controleert een bestelling en berekent de kosten ZONDER hem aan te maken. Je kunt je klant de prijs laten zien en vooraf nagaan of je saldo toereikend is. Er wordt niets van je saldo afgeschreven en de leverancier wordt niet benaderd.
Bestellingen in bulk
Met POST /orders/batch stuur je maximaal 50 bestellingen in één aanroep. De regels worden op volgorde verwerkt en elke regel krijgt zijn eigen resultaat: mislukt er één, dan worden de andere gewoon aangemaakt en zie je in het resultaat van die regel welke misging en waarom.
Gerelateerde objecten insluiten
Stuur je include=service mee op de bestel-endpoints, dan wordt het dienstobject in het antwoord ingesloten en hoef je geen tweede verzoek te doen.
Endpointreferentie
| Methode | Endpoint | Beschrijving |
|---|---|---|
| GET | /api/v3 | Discovery document: version, endpoints, limits and event types. |
| GET | /api/v3/openapi.json | OpenAPI 3.1 schema for this API. |
| GET | /api/v3/account | Account balance, currency and current rate-limit window. |
| PATCH | /api/v3/account | Set the low balance alert threshold that triggers account.low_balance. |
| GET | /api/v3/services | List services with filters and cursor pagination. |
| GET | /api/v3/services/{id} | Retrieve one service, including its order field schema. |
| GET | /api/v3/categories | List categories with their active service counts. |
| GET | /api/v3/platforms | List platform keys usable as the ?platform= filter, with counts. |
| POST | /api/v3/orders | Create an order. Supports the Idempotency-Key header. |
| POST | /api/v3/orders/preview | Validate an order and compute its charge without creating it. |
| POST | /api/v3/orders/batch | Create up to 50 orders in one call; each item reports its own result. |
| GET | /api/v3/orders | List your orders, newest first. |
| GET | /api/v3/orders/{id} | Retrieve one order. |
| POST | /api/v3/orders/{id}/cancel | Request cancellation. Only for services whose features.cancel is true. |
| POST | /api/v3/orders/{id}/refill | Request a refill for a completed order. |
| GET | /api/v3/refills | List your refill requests, newest first. |
| GET | /api/v3/refills/{id} | Retrieve one refill; refreshes its status from the provider. |
| GET | /api/v3/events | Read your event stream oldest-first; the polling alternative to webhooks. |
| GET | /api/v3/webhooks | List your webhook endpoints. |
| POST | /api/v3/webhooks | Register a webhook endpoint. The signing secret is returned once. |
| GET | /api/v3/webhooks/{id} | Retrieve one webhook endpoint. |
| PATCH | /api/v3/webhooks/{id} | Update a webhook endpoint's url, events, description or active state. |
| DELETE | /api/v3/webhooks/{id} | Delete a webhook endpoint and its delivery log. |
| POST | /api/v3/webhooks/{id}/test | Send a test event to this endpoint, ignoring its event filter. |
| POST | /api/v3/webhooks/{id}/rotate_secret | Generate a new signing secret. The old one stops working immediately. |
| GET | /api/v3/webhooks/{id}/deliveries | Delivery log for one endpoint: attempts, response codes and errors. |
OpenAPI-schema
Een machineleesbare beschrijving van elk endpoint. Geef dit bestand aan een clientgenerator (openapi-generator, Kiota) of aan Postman en je krijgt een kant-en-klare client in je eigen taal.
https://panelfollows.com/api/v3/openapi.jsonVeelgestelde vragen
Werkt mijn legacy-sleutel op v3?
Ja. Je hoeft geen nieuwe sleutel aan te maken om het te proberen. Stap in productie toch over op een v3-sleutel: die kun je intrekken en hij wordt niet als platte tekst bewaard.
Waarom zijn prijzen tekenreeksen?
Getallen met drijvende komma verliezen precisie bij decimale bedragen. Bedragen als tekenreeks teruggeven en aan jouw kant omzetten naar een decimaal type haalt die hele klasse afrondingsverschillen weg.
Waarom is het veld unit belangrijk?
De meeste diensten worden per 1000 stuks geprijsd (per_1000), maar pakketdiensten worden als één regel verkocht (per_order) en het tarief geldt voor het hele pakket. Koppelingen die dat onderscheid negeerden, rekenden pakketten een factor 1000 verkeerd.
Mijn bestelling is aangemaakt maar bleef op pending staan. Wat is er gebeurd?
De doorgifte aan de leverancier kan vertraagd zijn. Je saldo is gereserveerd en de bestelling raakt niet kwijt; ons team stuurt hem automatisch opnieuw door. Het veld processing_delayed markeert deze toestand.
Ondersteunen alle diensten annuleren en aanvullen?
Nee. Kijk naar features.cancel en features.refill op het dienstobject. Roep je het endpoint aan bij een dienst die het niet ondersteunt, dan volgt 400.
Kan ik beide API's tegelijk gebruiken?
Ja. Hetzelfde account, hetzelfde saldo, dezelfde bestellingen. Een bestelling die via v2 is geplaatst, lees je via v3 gewoon uit.
De klassieke reseller-API die in de hele branche standaard is. Dit is het formaat dat kant-en-klare panelsoftware verwacht.
Endpoint
POST https://panelfollows.com/api/v2
POST https://panelfollows.com/api/v2/trAuthenticatie
Bij elk verzoek gaat de parameter key mee. Houd je sleutel geheim en vernieuw hem meteen als hij is uitgelekt.
Formaat van verzoek en antwoord
Verzoeken worden met POST als formulier verstuurd (application/x-www-form-urlencoded) en antwoorden zijn JSON. Ook bij een fout komt HTTP 200 terug, met { "error": "..." } in de body.
Ook ondersteund, al is het tot nu toe nooit gedocumenteerd: je kunt de API met GET aanroepen en je mag de body als application/json versturen.
Verzoeklimiet
240 verzoeken per minuut per sleutel, plus 300 per minuut per IP. Verzoeken daarboven worden geweigerd met 429.
Acties en parameters
| action | Parameter | Beschrijving |
|---|---|---|
| services | key, action | Geeft alle actieve diensten (id, naam, categorie, tarief, min/max, aanvullen, annuleren, gespreide levering). |
| add | key, action, service, link, quantity[, runs, interval, comments, username, posts, min, max] | Maakt een bestelling aan. service is de id van de dienst in de catalogus. Voeg runs en interval toe voor gespreide levering, en de bijbehorende velden voor bijzondere types. |
| status | key, action, order | orders | Bestelstatus. Gebruik order voor één bestelling of een met komma's gescheiden orders-lijst voor meerdere. |
| balance | key, action | Accountsaldo en valuta. |
| refill | key, action, order | orders | Maakt een aanvulverzoek aan, dat rechtstreeks naar de leverancier gaat. |
| refill_status | key, action, refill | refills | Vraagt de status van een aanvulling op. |
| cancel | key, action, orders | Annuleert bestellingen. Werkt alleen bij diensten waarvan de leverancier annuleren ondersteunt. |
Voorbeeld
curl -X POST https://panelfollows.com/api/v2 \
-d "key=YOUR_API_KEY" \
-d "action=add" \
-d "service=1234" \
-d "link=https://instagram.com/username" \
-d "quantity=1000"
# Yanıt: { "order": 23501 }Antwoorden in het Turks
Zet /tr achter het adres om dienstnamen, categorieën, bestelstatussen en foutmeldingen in het Turks te ontvangen. De parameters, de acties en de opbouw van het antwoord zijn exact hetzelfde, en je sleutel werkt op beide adressen. Technische velden (type, refill_status, currency) blijven Engels om standaardcompatibel te blijven.
Overstappen naar v3
Overstappen is niet verplicht. Doe je het wel, dan blijft het grootste deel van je bedrijfslogica overeind omdat de parameternamen hetzelfde blijven; wat verandert, is het transport en de manier waarop je fouten uitleest.
- 1Verplaats de sleutel van het veld key in de body naar de header Authorization: Bearer.
- 2Roep een resourcepad aan in plaats van action=... (POST /orders in plaats van add).
- 3Controleer op fouten via de HTTP-statuscode en error.code in plaats van via "is er een error-veld".
- 4Vergelijk de bestelstatus met de machinewaarde, niet met de weergegeven tekst.
- 5Voeg een Idempotency-Key toe bij het aanmaken van bestellingen.
- 6Vervang het opvragen van status door webhooks.
Een sleutel geeft toegang tot je hele account. Deel hem niet, verwerk hem niet in code die bij de client draait en zet hem nooit in een openbare repository.
v3-sleutels
Je kunt zoveel sleutels aanmaken als je nodig hebt, ze allemaal labelen en stuk voor stuk intrekken. Aan onze kant bewaren we alleen een cryptografische samenvatting van de sleutel.
Maak een gratis accountLegacy-sleutel
De enige sleutel die de klassieke reseller-API (v2) gebruikt. Hij werkt ook op v3. Vernieuw je hem, dan vervalt de oude waarde onmiddellijk.
Beveiliging
- Bewaar de sleutel in een omgevingsvariabele, nooit in je broncode.
- Zet geen sleutel in code die in de browser draait; laat de verzoeken via je eigen server lopen.
- Maak per systeem een aparte sleutel, zodat het intrekken van de ene de andere niet raakt.
- Vermoed je een lek, neem dan eerst de nieuwe sleutel in gebruik en trek daarna pas de oude in.
Zodra een bestelling van status verandert, sturen we een ondertekende melding naar jouw server, zodat je de status nooit hoeft op te vragen.
Waarom webhooks?
Voortdurend opvragen is traag én verspillend: elke minuut duizenden bestellingen bevragen slurpt je verzoeklimiet op en toch hoor je pas minuten later van een wijziging. Met een webhook bereikt de wijziging je op het moment dat ze plaatsvindt.
Instellen
- 1Zorg voor een openbaar https-adres (lokale adressen en adressen in het interne netwerk worden geweigerd).
- 2Voeg het adres hieronder toe en bewaar de ondertekeningssleutel die één keer wordt getoond.
- 3Controleer de handtekening aan jouw kant en antwoord met 2xx.
- 4Gebruik de testknop om het hele traject van begin tot eind te bevestigen.
Wat wij versturen
POST /hooks/pf HTTP/1.1
Content-Type: application/json
Webhook-Id: evt_7f910fba7cd042ef9d9069ba5c074fa0
Webhook-Timestamp: 1787261223
Webhook-Signature: t=1787261223,v1=9c1e2b0d5c6a7e91...
{
"object": "event",
"id": "evt_7f910fba7cd042ef9d9069ba5c074fa0",
"type": "order.completed",
"created_at": "2026-08-21T00:27:03.531Z",
"data": {
"previous_status": "in_progress",
"order": {
"object": "order",
"id": 23501,
"status": "completed",
"status_label": "Tamamlandı",
"service": 1234,
"quantity": 1000,
"start_count": 4210,
"remains": 0,
"charge": "1.2340",
"currency": "USD"
}
}
}De handtekening controleren
Elk verzoek draagt een Webhook-Signature-header: t is het tijdstempel en v1 is de handtekening. De handtekening is de HMAC-SHA256 van de tekenreeks "<tijdstempel>.<ruwe body>", berekend met jouw geheime sleutel.
- 1Haal de waarden t en v1 uit de header.
- 2Controleer dat t niet ouder is dan 5 minuten, om herhaalaanvallen te blokkeren.
- 3Bereken de HMAC-SHA256 van "<t>.<ruwe body>" met jouw geheime sleutel.
- 4Vergelijk het resultaat in constante tijd met v1 en weiger het verzoek als het niet klopt.
Voorbeeld van controle
import crypto from "node:crypto";
import express from "express";
const app = express();
// ÖNEMLİ: imza HAM gövde üzerinden hesaplanır. JSON'a çevirip yeniden
// dizeye dönüştürürseniz boşluklar değişir ve imza tutmaz.
app.post("/hooks/pf", express.raw({ type: "application/json" }), (req, res) => {
const raw = req.body.toString("utf8");
const header = req.get("Webhook-Signature") ?? "";
const m = /t=(\d+),v1=([0-9a-f]+)/.exec(header);
if (!m) return res.sendStatus(400);
const [, timestamp, signature] = m;
// Tekrar saldırısına karşı: 5 dakikadan eski damgayı reddet.
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return res.sendStatus(400);
const expected = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(`${timestamp}.${raw}`, "utf8")
.digest("hex");
const ok =
expected.length === signature.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
if (!ok) return res.sendStatus(401);
const event = JSON.parse(raw);
// 2xx dönmezseniz gönderim artan aralıklarla tekrar denenir.
res.sendStatus(200);
if (event.type === "order.completed") {
// ... siparişi kendi sisteminizde tamamlandı olarak işaretleyin
}
});Opnieuw proberen
De eerste poging vindt plaats op het moment van de gebeurtenis. Komt er iets anders dan 2xx terug, of lukt de verbinding niet, dan wordt de bezorging opnieuw geprobeerd na 1 minuut, 5 minuten, 30 minuten, 2 uur en 6 uur. Na in totaal 6 pogingen wordt de bezorging als mislukt gemarkeerd en verschijnt ze in het bezorglogboek.
Gebeurtenistypes
Je abonneert je op de types die je nodig hebt, of je ontvangt ze allemaal. Eén statuswijziging levert precies één gebeurtenis op, met het type dat het beste bij de nieuwe status past.
| order.created | Er is een bestelling aangemaakt. |
| order.processing | De leverancier is met de bestelling begonnen. |
| order.completed | De bestelling is afgerond. |
| order.partial | De bestelling is deels geleverd en de rest is terugbetaald. |
| order.canceled | De bestelling is geannuleerd of terugbetaald. |
| order.updated | De status is op een andere manier gewijzigd. |
| refill.created | Er is een aanvulling aangevraagd. |
| refill.updated | De status van een aanvulling is gewijzigd. |
| account.low_balance | Je saldo is onder de drempel gezakt die je met PATCH /account hebt ingesteld. Wordt verzonden bij het passeren, niet bij elke bestelling, en wordt opnieuw scherpgesteld zodra het saldo er weer boven komt. |
Als je geen webhook kunt hosten
Dezelfde gebeurtenissen lees je met een cursor uit via GET /api/v3/events. Gebruik deze weg tijdens lokaal ontwikkelen, als je geen vast IP hebt of als je achter een firewall zit.
// Webhook kuramıyorsanız (yerelde geliştirme, sabit IP yok) aynı bilgiyi
// imleçle çekebilirsiniz. İmleci kendi tarafınızda saklayın.
let cursor = loadCursor(); // en son işlediğiniz olayın "cursor" değeri
const url = new URL("https://panelfollows.com/api/v3/events");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("starting_after", String(cursor));
const res = await fetch(url, { headers: { Authorization: "Bearer YOUR_API_KEY" } });
const { data, has_more } = await res.json();
for (const event of data) {
handle(event); // sizin işleyiciniz
cursor = event.cursor; // imleci ilerlet
}
saveCursor(cursor);Fouten (48)
| Code | Status | Beschrijving |
|---|---|---|
| missing_api_key | 401 | Geen API-sleutel meegestuurd. Stuur deze mee als 'Authorization: Bearer <key>'. |
| invalid_api_key | 401 | De opgegeven API-sleutel is niet geldig. |
| revoked_api_key | 401 | Deze API-sleutel is ingetrokken en kan niet meer worden gebruikt. |
| account_banned | 403 | Dit account is geblokkeerd. |
| account_suspended | 403 | Dit account is opgeschort. |
| insufficient_scope | 403 | Deze API-sleutel heeft geen rechten voor dit endpoint. |
| invalid_json | 400 | De body van het verzoek is geen geldige JSON. |
| unsupported_content_type | 415 | Niet-ondersteund Content-Type. Gebruik application/json of application/x-www-form-urlencoded. |
| method_not_allowed | 405 | Deze HTTP-methode is niet toegestaan op dit endpoint. |
| payload_too_large | 413 | De body van het verzoek is te groot. |
| missing_parameter | 400 | Een verplichte parameter ontbreekt. |
| invalid_parameter | 400 | Een parameter heeft een ongeldige waarde. |
| invalid_link | 400 | De link ontbreekt of is geen geldige http(s)-URL. |
| invalid_quantity | 400 | De hoeveelheid is geen geldig positief geheel getal. |
| quantity_out_of_range | 400 | De hoeveelheid valt buiten het bereik dat deze dienst toestaat. |
| invalid_comments | 400 | Het veld met reacties is leeg of bevat te veel regels. |
| invalid_username | 400 | De gebruikersnaam is niet geldig voor deze dienst. |
| invalid_subscription | 400 | De abonnementsparameters zijn niet geldig. |
| invalid_runs | 400 | De waarde van 'runs' is niet geldig voor gespreide levering. |
| invalid_interval | 400 | De waarde van 'interval' is niet geldig voor gespreide levering. |
| dripfeed_not_supported | 400 | Deze dienst ondersteunt geen gespreide levering. |
| missing_required_field | 400 | Een veld dat voor dit type dienst vereist is, ontbreekt of is ongeldig. |
| service_inactive | 400 | Deze dienst is op dit moment niet bestelbaar. |
| invalid_cursor | 400 | De paginatiecursor is niet geldig. |
| invalid_limit | 400 | De parameter 'limit' valt buiten het toegestane bereik. |
| invalid_webhook_url | 400 | De webhook-URL moet een openbaar https://-adres zijn. |
| invalid_events | 400 | Een of meer van de opgegeven gebeurtenistypen zijn onbekend. |
| batch_too_large | 400 | Te veel items in één batchverzoek. |
| cancel_not_supported | 400 | Deze dienst ondersteunt annuleren niet. |
| refill_not_supported | 400 | Deze dienst biedt geen aanvulling. |
| unknown_endpoint | 404 | Onbekend endpoint. De beschikbare routes staan in de API-referentie. |
| service_not_found | 404 | Er bestaat geen dienst met dit id. |
| order_not_found | 404 | Er bestaat geen bestelling met dit id op uw account. |
| refill_not_found | 404 | Er bestaat geen aanvulling met dit id op uw account. |
| webhook_not_found | 404 | Er bestaat geen webhook-endpoint met dit id op uw account. |
| order_not_cancelable | 409 | Deze bestelling kan door haar huidige status niet meer worden geannuleerd. |
| cancel_rejected | 409 | De leverancier heeft het annuleringsverzoek geweigerd. |
| order_not_completed | 409 | Aanvulling kan alleen worden aangevraagd voor een voltooide bestelling. |
| duplicate_link | 409 | Er loopt al een bestelling voor deze link. Wacht tot die voltooid is. |
| idempotency_key_reuse | 409 | Deze Idempotency-Key is al gebruikt met een andere verzoekbody. |
| idempotency_in_progress | 409 | Een verzoek met deze Idempotency-Key wordt nog verwerkt. Probeer het zo opnieuw. |
| webhook_limit_reached | 409 | U hebt het maximale aantal webhook-endpoints bereikt. |
| insufficient_balance | 402 | Uw saldo is niet toereikend voor deze bestelling. |
| rate_limit_exceeded | 429 | Verzoeklimiet overschreden. Zie de Retry-After responseheader. |
| provider_error | 502 | De leverancier gaf een fout terug. Probeer het opnieuw. |
| refill_failed | 502 | Het aanvullingsverzoek is door de leverancier geweigerd. |
| service_temporarily_unavailable | 503 | Deze dienst is tijdelijk niet beschikbaar. Probeer het later opnieuw. |
| internal_error | 500 | Er is aan onze kant een onverwachte fout opgetreden. |