API-Dokumentation
Schick eine URL und deinen Proxy. Orpheus erkennt die Anti-Bot-Challenge, löst sie und gibt dir die Seite zurück — mit einer Session, die du für die nächsten Requests wiederverwenden kannst.
Schnellstart
- Melde dich in der Konsole an und erstelle im Tab API-Schlüssel einen API-Schlüssel. Kopiere ihn: Er wird nur einmal angezeigt.
- Halte einen Sticky-Proxy bereit, Residential oder ISP (eine Exit-IP, die mindestens 10 Minuten bleibt).
- Ruf
POST /v1/fetchmit der URL und dem Proxy auf.
curl -X POST https://orpheus-api.lapetiteagora.fr/v1/fetch \ -H "Authorization: Bearer $LPA_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://www.example.com/", "proxy": "http://user:pass@proxy.example:8080" }'
import os, requests resp = requests.post( "https://orpheus-api.lapetiteagora.fr/v1/fetch", headers={"Authorization": f"Bearer {os.environ['LPA_KEY']}"}, json={ "url": "https://www.example.com/", "proxy": "http://user:pass@proxy.example:8080", }, timeout=70, ) page = resp.json() print(page["status"], page["solved"], page["session_id"])
const resp = await fetch("https://orpheus-api.lapetiteagora.fr/v1/fetch", { method: "POST", headers: { Authorization: `Bearer ${process.env.LPA_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ url: "https://www.example.com/", proxy: "http://user:pass@proxy.example:8080", }), }); const page = await resp.json(); console.log(page.status, page.solved, page.session_id);
Stell in deinem Client ein Timeout von etwa 70 Sekunden ein: Das Lösen einer Challenge kann ein paar Sekunden dauern, manchmal länger.
Authentifizierung
Jeder Request trägt deinen API-Schlüssel im Header Authorization:
Authorization: Bearer lpa_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Schlüssel werden in der Konsole erstellt und widerrufen. Behandle sie wie Passwörter: Bewahre sie serverseitig auf, nie in einem Browser oder einem öffentlichen Repository. Ein widerrufener Schlüssel oder ein gesperrtes Konto bekommt sofort 401 invalid_key.
Eine Seite abrufen
Request-Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
urlPflicht | string | Die abzurufende Seite, http oder https. |
proxy | string | Pflicht, um eine Session zu starten. http://user:pass@host:port, https://… oder socks5://…. Lass ihn weg (oder schick denselben Wert), wenn du eine session_id mitgibst. |
session_id | string | Verwendet eine Session wieder, die ein früherer Aufruf zurückgegeben hat. Siehe Sessions. |
method | string | GET (Standard), POST, PUT, PATCH, DELETE, HEAD oder OPTIONS. |
headers | object | Zusätzliche Request-Header als Strings {"Name": "value"}. Die Browser-Header (User-Agent, Client Hints…) sind bereits gesetzt. |
body | string | Request-Body für POST/PUT/PATCH. |
body_encoding | string | text (Standard) oder base64 für einen binären Body. |
cookies | object · array | Cookies, die vor dem Request zur Session hinzugefügt werden. Siehe Cookies. |
preset | string | Browser-Fingerprint, festgelegt beim Erstellen der Session. Standard chrome-latest-windows (behalte ihn, solange du keinen guten Grund hast). |
Antwort
Die API antwortet mit 200, sobald die Zielseite geantwortet hat — egal, welchen Status die Seite selbst liefert. Diesen Status liest du in status.
{
"status": 200,
"headers": { "content-type": ["text/html; charset=utf-8"] },
"body": "<!doctype html>…",
"encoding": "text",
"url": "https://www.example.com/",
"session_id": "s_Ij4oudr1bYPzUA8U3sdlACAf",
"solved": ["datadome"],
"cookies": [{ "name": "datadome", "value": "…", "domain": ".example.com", "path": "/" }],
"elapsed_ms": 2343
}| Feld | Beschreibung |
|---|---|
status | HTTP-Status, den die Zielseite zurückgegeben hat. |
headers | Response-Header; jeder Wert ist eine Liste von Strings. |
body · encoding | Die Seite. encoding ist text (UTF-8) oder base64 für binäre Inhalte (Bilder, PDF…). |
url | Finale URL, nach Weiterleitungen. |
session_id | Schick sie zurück, um dieselbe Identität zu behalten. Wird auch bei den meisten Fehlern zurückgegeben. |
solved | In diesem Aufruf gelöste Schutzmechanismen: akamai, datadome, incapsula, kasada, cloudflare, ticketmaster. Leer, wenn nichts gelöst werden musste. |
cookies | Alle Cookies der Session nach dem Aufruf. |
elapsed_ms | Zeit auf unserer Seite, inklusive Lösen. |
Sessions
Anti-Bot-Cookies sind an die Browser-Identität gebunden, die sie erhalten hat: IP, Fingerprint, Cookie-Jar. Eine Session hält diese Identität für dich fest — eine einmal gelöste Challenge bleibt gelöst.
- Der erste Aufruf (mit
proxy, ohnesession_id) erstellt eine Session und gibt ihresession_idzurück. - Schick diese
session_idbei den nächsten Aufrufen mit: derselbe Proxy, derselbe Fingerprint, dieselben Cookies. Weitere Seiten kommen meist in wenigen hundert Millisekunden zurück, mitsolved: []. - Eine Session läuft nach 30 Minuten ohne Requests ab. Jeder Request verlängert sie.
- Eine Session behält ihren Proxy, solange sie lebt. Ein anderer
proxyzusammen mit einersession_idergibt409 proxy_mismatch: Starte stattdessen eine neue Session. - Ein Request gleichzeitig pro Session. Ein zweiter, paralleler Request wartet bis zu 10 Sekunden und bekommt dann
409 session_busy. Für mehr Tempo lässt du mehrere Sessions parallel laufen, jede mit eigenem Proxy.
import os, requests API = "https://orpheus-api.lapetiteagora.fr/v1/fetch" HEADERS = {"Authorization": f"Bearer {os.environ['LPA_KEY']}"} def fetch(**payload): r = requests.post(API, headers=HEADERS, json=payload, timeout=70) data = r.json() if r.status_code != 200: raise RuntimeError(data["error"]) return data # 1. Zuerst die Startseite: erstellt die Session und löst die Challenge home = fetch(url="https://www.shop.example/", proxy="http://user:pass@proxy.example:8080") # 2. Dann die Produktseite, mit derselben Identität product = fetch( url="https://www.shop.example/product/42", session_id=home["session_id"], headers={"Referer": "https://www.shop.example/"}, ) print(product["status"], product["solved"])
# 1. Startseite: merk dir die session_id aus der Antwort curl -s -X POST https://orpheus-api.lapetiteagora.fr/v1/fetch \ -H "Authorization: Bearer $LPA_KEY" -H "Content-Type: application/json" \ -d '{"url":"https://www.shop.example/","proxy":"http://user:pass@proxy.example:8080"}' # 2. Produktseite in derselben Session curl -s -X POST https://orpheus-api.lapetiteagora.fr/v1/fetch \ -H "Authorization: Bearer $LPA_KEY" -H "Content-Type: application/json" \ -d '{"url":"https://www.shop.example/product/42","session_id":"s_…", "headers":{"Referer":"https://www.shop.example/"}}'
Fehler
Fehler haben einen Status ungleich 200 und immer dieselbe Form. Wenn eine Session existiert, ist ihre session_id enthalten.
{
"error": { "code": "proxy_blocked", "message": "…" },
"session_id": "s_…"
}| Status | Code | Was tun |
|---|---|---|
| 400 | invalid_request | Korrigiere den Request: url fehlt, proxy fehlt für eine neue Session, ungültiges Feld, private oder nicht erreichbare Adresse. |
| 401 | invalid_key | Schlüssel fehlt, ist falsch oder widerrufen, oder das Konto ist gesperrt. |
| 402 | quota_exceeded | Monatskontingent erreicht. Es wird am 1. des Monats (UTC) zurückgesetzt. |
| 404 | session_not_found | Die Session ist abgelaufen (30 Min. inaktiv) oder wurde geschlossen. Starte eine neue. |
| 409 | proxy_mismatch | Eine Session behält ihren Proxy. Starte für einen anderen Proxy eine neue Session. |
| 409 | session_busy | Ein anderer Request nutzt diese Session. Warte oder nimm eine andere Session. |
| 413 | response_too_large | Die Seite ist größer als 5 MB. |
| 422 | proxy_blocked | Die Seite hat diese IP gesperrt. Wechsle den Proxy und starte eine neue Session. |
| 429 | too_many_concurrent | Zu viele laufende Requests für dein Konto. Versuch es erneut, sobald einer fertig ist. |
| 502 | challenge_failed | Die Challenge konnte nicht gelöst werden. Versuch es einmal erneut; wenn es bleibt, wechsle den Proxy. |
| 502 | solver_error · transport_error | Vorübergehendes Problem beim Solver oder im Netzwerk (oft der Proxy). Versuch es nach kurzer Pause erneut. |
| 504 | timeout | Keine Antwort in der vorgesehenen Zeit. Versuch es erneut; die Session bleibt nutzbar. |
| 500 | internal_error | Problem auf unserer Seite. Versuch es erneut und sag uns Bescheid, wenn es bleibt. |
Faustregel für Retries: Wiederhole 429, 502, 504 und 500 mit kurzem Backoff. Wiederhole nie einen 422 in derselben Session: Wechsle den Proxy.
Limits
| Limit | Wert |
|---|---|
| Requests pro Monat (Beta) | 20.000 pro Konto, Reset am 1. des Monats (UTC). Jeder Aufruf von /v1/fetch, der die Seite erreicht, zählt — auch wenn das Lösen danach scheitert; vorab abgelehnte Aufrufe (400, 401, 402, 404, 409, 429) zählen nicht. |
| Parallele Requests | Standardmäßig 5 pro Konto (siehe deinen Tab Konto). |
| Zeit pro Request | Etwa 55 Sekunden, inklusive Lösen. |
| Größe der Antwort | 5 MB Seiteninhalt. |
| Lebensdauer einer Session | 30 Minuten nach dem letzten Request. |
| Cookies | 50 pro Request, 4.096 Zeichen pro Wert. |
Verbrauch, gelöste Challenges und deine letzten Requests findest du in der Konsole.
Weitere Endpoints
Die in diesem Monat verbrauchten Requests, dein Kontingent und die tägliche Aufschlüsselung der letzten 30 Tage (Requests, Erfolge, Fehler, Bytes, Lösungen pro Schutzmechanismus).
curl -s https://orpheus-api.lapetiteagora.fr/v1/usage -H "Authorization: Bearer $LPA_KEY"Schließt eine Session sofort (sonst läuft sie von selbst ab). Gibt {"deleted": true} zurück, oder 404, wenn sie nicht mehr existiert.
curl -s -X DELETE https://orpheus-api.lapetiteagora.fr/v1/sessions/s_… -H "Authorization: Bearer $LPA_KEY"Best Practices
- Nur Sticky-Proxys. Ein rotierender Proxy wechselt die IP zwischen Requests und macht die gerade erhaltenen Cookies ungültig. Plane Sessions von 10 Minuten oder mehr ein.
- Eine Session pro Identität. Nutze sie für alle Seiten eines Ablaufs; öffne zum Skalieren mehr Sessions (mit mehr Proxys).
- Surf natürlich. Lade zuerst die Start- oder Kategorieseite, dann die Produktseite mit einem
Referer-Header. Direkte Aufrufe tiefer Seiten werden häufiger markiert. - Hämmer nicht auf eine Session ein. Löse die Challenge mit einem Request und mach dann weiter; vermeide Bursts von derselben IP.
- Bei
proxy_blockedleg die Session und ihren Proxy eine Weile beiseite; eine verbrannte IP bleibt verbrannt. - Respektiere die Seiten, die du aufrufst. Du bist dafür verantwortlich, ihre Nutzungsbedingungen und die für dich geltenden Gesetze einzuhalten.