Production davranisiyla uyumlu dokumantasyon

XAPI Dokumantasyonu

XAPI, public client isteklerini master/orchestrator uzerinden managed X node agina dagitir. Default entegrasyonlar icinPOST /api/execute/legacy response dondurur; X API v2'ye yakin public yollar/2/users...altinda ayrica sunulur.

Toplam worker

20

X1 10 + X2 10

Kapasite

20/20

X1 ve X2 toplam concurrency

Agir is kapasitesi

6

Node basina en fazla 3 adet count>=2001 is

Client - Master - Queue - Node Pull - Execute - Complete - Normalize - Client
Client istegi master tarafinda queued job olarak olusturulur. Managed node bos kapasitesi kadar batch claim yapar, isi calistirir, sonucu complete endpointine gonderir. Master response formatini bozmadan normalize eder ve client'a doner.

Authentication

Public client isteklerinde zorunlu header X-API-Key alanidir. Dashboard oturum tokeni veya node tokeni public API icin kullanilmaz.

Header
X-API-Key: <key>
Preferred key
Panelde uretilen secret API key.
Legacy uyumluluk
Mevcut eski entegrasyonlar icin key id kullanimi da desteklenir.
Authentication example
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"user_tweets_fetch","params":{"username":"celalyaziyor","count":2}}'

Ana Endpoint

Method
POST
URL
https://archepolis.xyz/api/execute/
Body
{ "type": "user_tweets_fetch", "params": { ... } }
Default response
Legacy / TemizVeri uyumlu response.
V2 opt-in
X-Response-Format: v2
Max count
Senkron user tweet isteklerinde 3000.
user_tweets_fetch
Kullanici tweetlerini dondurur.
user_tweets
user_tweets_fetch alias.
username_fetch
user_tweets_fetch alias; canonical node capability username_fetch.
user_date_range_fetch
since/until araliginda date-aware pagination yapar; count aralik icinden dondurulecek maksimum sonuc sayisidir.
user_by_username
Tek normalize kullanici objesi dondurur. Alias: user_fetch.
bulk_users
Birden fazla kullanici objesi dondurur. Eksik hedefler errors[] ve meta.lookup_errors icinde raporlanir. Alias: bulk_users_fetch.
search_fetch
Arama sorgusuna gore tweet/result listesi dondurur.
tweet_detail_fetch
Yeni node capability; /2/tweets/{id} public endpointi tarafindan kullanilir.
user_lookup
Yeni node capability; /2/users/by/username/{username} public endpointi tarafindan kullanilir.
user_lookup_batch
Yeni node capability; /2/users?usernames=a,b,c public endpointi tarafindan kullanilir.
user_tweets_by_id_fetch
Yeni node capability; /2/users/{id}/tweets public endpointi tarafindan kullanilir.

user_tweets_fetch

username
Kullanici adi. @ olmadan gonderilir.
user_id
Node destekliyorsa pass-through parametre olarak iletilir; public sozlesmede username onerilir.
count
1-3000. count > 3000 senkron execute icin COUNT_TOO_LARGE dondurur.
exclude
["originals", "quotes", "replies", "retweets"]
referenced_depth
Geriye uyumlu ortak derinlik: 1-3, varsayilan 1.
self_reference_depth
0-100. Timeline veya root tweet yazariyla ayni yazara ait referans hop siniri.
other_reference_depth
0-100. Diger yazarlara ait referans hop siniri.
timeout_seconds
Async agir islerde opsiyonel 60-7200 saniye job timeout override degeri.
months
Node destekliyorsa pass-through parametre olarak iletilir.
since_id
Delta destegi. Cache dahil yalniz bu ID'den yeni tweetler doner; meta.since_id_reached tabana ulasilip ulasilmadigini gosterir.
query_flag
Tweet objelerine izleme etiketi olarak kopyalanir.
response_format
"v2"
Son 2 tweet
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_tweets_fetch",
    "params": {
      "username": "celalyaziyor",
      "count": 2
    }
  }'
3000 tweet
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_tweets_fetch",
    "params": {
      "username": "SinemasaYT",
      "count": 3000
    }
  }'
since_id delta
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_tweets_fetch",
    "params": {
      "username": "celalyaziyor",
      "count": 100,
      "since_id": "2068000000000000000",
      "query_flag": "daily_sync"
    }
  }'
v2 user tweets
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Response-Format: v2" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_tweets_fetch",
    "params": {
      "username": "moononleo",
      "count": 80
    }
  }'
reply timeline, retweet ve quote haric
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Response-Format: v2" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_tweets_fetch",
    "params": {
      "username": "elonmusk",
      "count": 100,
      "exclude": ["retweets", "quotes"],
      "self_reference_depth": 100,
      "other_reference_depth": 100
    }
  }'

Varsayilan exclude=[] Posts & replies timeline kullanir. Posts-only sonuc icin exclude:["replies"] gonderilir. Eski include_replies yalniz geriye uyumluluk icin master tarafinda exclude listesine cevrilir ve node'a iletilmez. count filtrelerden sonra uygulanan kesin ust sinirdir. Expansion objeleri root data, result_count ve sonuc bazli faturalama sayisini artirmaz. Split parametre verilmezse eski referenced_depth davranisi korunur. 0 ilgili eksendeki expansion'i kapatir, root referenced_tweets baglantilarini silmez. Secilen mod ve filtreler meta.timeline, efektif derinlikler ve dinamik butce ise meta.referenced_enrichment icinde doner.

X API v2 Tarzi Public Endpointler

Bu yollar X API v2 endpoint mantigina yakindir ve daima normalize v2 response dondurur. Arkada ayni master queue ve node pull akisi kullanilir; legacy /api/execute/ formati degismez.

GET /2/tweets/{id}
Tweet detail lookup. referenced_depth=1..3 veya self_reference_depth=0..100 ve other_reference_depth=0..100 desteklenir.
GET /2/users/by/username/{username}
Tek kullanici lookup. username path parametresi @ olmadan kullanilir.
GET /2/users
usernames=a,b,c veya ids=1,2 ile en fazla 100 kullanici. Eksikler errors[] ve meta.lookup_errors icinde gelir. Cloudflare-safe senkron kullanim icin 25 veya daha az; daha buyuk listelerde async jobs onerilir.
GET /2/users/{id}/tweets
user_id bazli tweet cekimi. Ortak veya split referans derinligi query parametreleri desteklenir.
Auth
X-API-Key
Response
data, includes.tweets/users/media/places/polls, meta, errors[].
Hata formati
Invalid request/auth/upstream hatalari X API v2 problem URL'leri ile errors[] icinde doner.
Gizli alanlar
Node credential, proxy, cookie, token ve account bilgileri public response'a cikarilmaz.
tweet detail
curl "https://archepolis.xyz/2/tweets/2095223570918166647?self_reference_depth=100&other_reference_depth=100" \
  -H "X-API-Key: YOUR_API_KEY"
user by username
curl https://archepolis.xyz/2/users/by/username/celalyaziyor \
  -H "X-API-Key: YOUR_API_KEY"
bulk users
curl "https://archepolis.xyz/2/users?usernames=celalyaziyor,SinemasaYT" \
  -H "X-API-Key: YOUR_API_KEY"
bulk users by id
curl "https://archepolis.xyz/2/users?ids=15828364,783214" \
  -H "X-API-Key: YOUR_API_KEY"
user id tweets
curl "https://archepolis.xyz/2/users/44196397/tweets?max_results=100&self_reference_depth=100&other_reference_depth=100" \
  -H "X-API-Key: YOUR_API_KEY"

Tarih Araligi

user_date_range_fetch, yeni tweetleri until sinirina kadar atlar ve pencere icinden count kadar sonuc bulana, since sinirina ulasana veya cursor bitene kadar geriye sayfalar. meta.date_range_scan taranan tarih kapsamini ve range_complete durumunu kanitlar.

user date range
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_date_range_fetch",
    "params": {
      "username": "celalyaziyor",
      "since": "2026-01-01",
      "until": "2026-06-01",
      "count": 5
    }
  }'
async user date range
curl -X POST https://archepolis.xyz/api/jobs/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "target_username": "celalyaziyor",
    "job_type": "user_date_range_fetch",
    "params": {
      "since": "2026-01-01",
      "until": "2026-06-01",
      "count": 20
    }
  }'

Async istekte master mantiksal tipi node'un username_fetch capability'sine cevirir. Tamamlanan isin result_data.meta.date_range_scan alanindaki range_complete, partial, scan_limit_reached ve stop_reason degerleri tarama kapsamını gosterir.

Async Jobs ve Iptal

Burst trafik icin Prefer: respond-async kullanin. Master isi PostgreSQL'e commit ettikten sonra HTTP 202 ve job_id doner. Tek istekte en fazla 500 isi kalici kuyruga yazmak icin POST /api/jobs/batch kullanilir. Varsayilan senkron /api/execute ve TemizVeri formati degismez.

Durumlar
queued, processing, waiting_rate_limit, retrying, timed_out, cancellation_requested, cancelled, completed, failed, late_completed, late_failed.
Terminal
completed, failed, cancelled, late_completed ve late_failed tekrar acilmaz.
Idempotency
Ayni Idempotency-Key orijinal job/batch sonucunu dondurur; ikinci scraping isi olusturmaz.
Rate-limit progress
progress_code=ACCOUNT_RATE_LIMITED terminal hata degildir; node 15 uygun hesaba kadar rotate eder.
Partial
Toplanan tweetler silinmez; completed + meta.partial=true + meta.limited=true doner.
Verisiz exhaustion
waiting_rate_limit durumunda 900 saniye bekler, kontrollu olarak en fazla 3 kez denenir.
retry_count
Basarisiz node denemesi sayisi. 999 ve uzeri timeout/legacy terminal sentinel degeridir.
Cancel
POST /api/jobs/{job_id}/cancel
async execute
curl -X POST https://archepolis.xyz/api/execute/   -H "X-API-Key: YOUR_API_KEY"   -H "Prefer: respond-async"   -H "Idempotency-Key: customer-request-123"   -H "Content-Type: application/json"   -d '{"type":"user_tweets_fetch","params":{"username":"celalyaziyor","count":1000}}'
500 job batch
curl -X POST https://archepolis.xyz/api/jobs/batch   -H "X-API-Key: YOUR_API_KEY"   -H "Idempotency-Key: customer-batch-20260920-1"   -H "Content-Type: application/json"   -d '{"jobs":[{"client_request_id":"row-1","type":"user_tweets_fetch","params":{"username":"celalyaziyor","count":1000}}]}'

curl https://archepolis.xyz/api/job-batches/BATCH_ID   -H "X-API-Key: YOUR_API_KEY"

Default / Legacy Response

Header verilmezse default response legacy formatta kalir. Bu format TemizVeri mevcut entegrasyonu icin korunur.

success
Boolean basari sinyali.
data
Tweet, user veya liste payload'i.
includes
tweets, users, media, places, polls expansion alanlari.
errors
Standart error object listesi.
meta
job_id, node_id, duration_ms, token_usage, result_count, cost, collection_date.
error
Legacy tekil hata ozeti veya null.
live-compatible legacy sample
{
  "success": true,
  "data": [
    {
      "id": "2068612761701974255",
      "text": "Tweet text",
      "author_id": "15828364",
      "created_at": "2026-06-21T08:31:30.000Z",
      "conversation_id": "2068612761701974255",
      "public_metrics": {
        "retweet_count": 1,
        "reply_count": 11,
        "like_count": 26,
        "quote_count": 0,
        "bookmark_count": 6,
        "impression_count": 1751,
        "total_engagement": 44
      },
      "context_annotations": [],
      "query_flag": null,
      "edit_history_tweet_ids": ["2068612761701974255"],
      "reply_settings": null,
      "in_reply_to_user_id": null,
      "note_tweet": { "text": "Full note text when X returns it" },
      "geo": { "place_id": null, "coordinates": null, "place": null },
      "withheld": null,
      "source": "<a href=\"https://mobile.twitter.com\" rel=\"nofollow\">Twitter Web App</a>",
      "attachments": { "media_keys": [], "poll_ids": [] }
    }
  ],
  "includes": {
    "tweets": [],
    "media": [],
    "places": [],
    "polls": [],
    "users": [
      {
        "id": "15828364",
        "username": "celalyaziyor",
        "verified": false,
        "pinned_tweet_id": null,
        "listed_count": 0,
        "public_metrics": {
          "followers_count": 2251,
          "following_count": 2010,
          "tweet_count": 1588,
          "listed_count": 0
        }
      }
    ]
  },
  "errors": [],
  "collection_date": "2026-06-22T07:36:14.103549Z",
  "meta": {
    "job_id": "job_example",
    "node_id": "node_example",
    "duration_ms": 12345,
    "token_usage": 2,
    "result_count": 2,
    "cost": 0.05,
    "cached": false,
    "collection_date": "2026-06-22T07:36:14.103549Z"
  },
  "error": null
}

V2 Response Opt-in

V2 format header, query/body response_format=v2 veya body response_format: "v2" ile istenebilir. V2 response ust seviyede success alanini kullanmaz.

data[]
Normalize tweet veya user objeleri.
includes.users[]
Normalize user expansion.
includes.tweets[]
RT/quote/reply referenced tweet objeleri. Node includes.tweets gonderirse korunur.
includes.media[]
media_key, type, url, preview_image_url, width, height, duration_ms, alt_text ve variants[].
includes.places[]
Geo/place expansion varsa dolu, yoksa bos array.
includes.polls[]
Poll expansion varsa dolu, yoksa bos array.
errors[]
Daima array.
meta
job_id, node_id, result_count, collection_date, cost, response_contract_version, timeline_contract_revision, timeline, thread_completion, artifact_entries_dropped, since_id_reached, longform_enrichment, referenced_enrichment, lookup_errors ve partial/limited alanlari.
Tweet fields
id, text, created_at, author_id, conversation_id, referenced_tweets.
Referenced tweets
RT/quote/reply orijinal tweetleri node includes.tweets dondururse public response'ta korunur.
Expansion depth
self_reference_depth 0-100 ve other_reference_depth 0-100. Eski referenced_depth 1-3 geriye uyumludur; node tum katmanlari ayni duz includes.tweets[] listesine ekler.
Metrics
public_metrics.impression_count ve public_metrics.total_engagement dahil.
Delta/meta fields
query_flag, edit_history_tweet_ids, context_annotations.
Reply/note
reply_settings, in_reply_to_user_id, note_tweet.text.
Geo/legal/source
geo.place_id, geo.coordinates, withheld, source.
Attachments/entities
Media detaylari preview, boyut, sure, alt_text ve video variants alanlarini korur. URL entity: url/expanded_url/display_url/unwound_url; kaynakta yoksa null.
Timeline meta
Effective exclude listesi, secilen timeline modu ve filtreler meta.timeline icinde korunur.
live-compatible v2 sample
{
  "data": [
    {
      "id": "2068939481344868780",
      "text": "Tweet text",
      "author_id": "1465736985738416133",
      "created_at": "2026-06-22T06:09:46.000Z",
      "conversation_id": "2068939481344868780",
      "public_metrics": {
        "retweet_count": 1,
        "reply_count": 0,
        "like_count": 0,
        "quote_count": 0,
        "bookmark_count": 0,
        "impression_count": 0,
        "total_engagement": 1
      },
      "referenced_tweets": [{ "type": "retweeted", "id": "2067603736915018160" }],
      "context_annotations": [],
      "edit_history_tweet_ids": ["2068939481344868780"],
      "reply_settings": null,
      "in_reply_to_user_id": null,
      "note_tweet": { "text": null },
      "geo": { "place_id": null, "coordinates": null, "place": null },
      "withheld": null,
      "source": "<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone</a>",
      "attachments": { "media_keys": [], "poll_ids": [] },
      "query_flag": null
    }
  ],
  "includes": {
    "tweets": [
      {
        "id": "2067603736915018160",
        "text": "Original RT/quote/reply tweet full text",
        "author_id": "44196397",
        "public_metrics": {
          "retweet_count": 4,
          "reply_count": 2,
          "like_count": 95,
          "quote_count": 1,
          "bookmark_count": 8,
          "impression_count": 4200,
          "total_engagement": 110
        }
      }
    ],
    "users": [
      {
        "id": "1465736985738416133",
        "username": "moononleo",
        "verified": false,
        "pinned_tweet_id": null,
        "listed_count": 0,
        "public_metrics": {
          "followers_count": 32560,
          "following_count": 112,
          "tweet_count": 9051,
          "listed_count": 0
        }
      }
    ],
    "media": [],
    "places": [],
    "polls": []
  },
  "meta": {
    "job_id": "job_example",
    "node_id": "node_example",
    "result_count": 3,
    "collection_date": "2026-06-22T07:36:18.433622Z",
    "cost": 0.05,
    "response_contract_version": 2,
    "timeline": {
      "mode": "with_replies",
      "exclude": []
    },
    "longform_enrichment": {
      "limited": false,
      "time_budget_exceeded": false
    },
    "referenced_enrichment": {
      "enabled": true,
      "depth": 1,
      "self_reference_depth": 100,
      "other_reference_depth": 100,
      "depth_mode": "axis",
      "owner_author_id": "44196397",
      "recursive_expansion": true,
      "referenced_total": 1,
      "referenced_unique": 1,
      "already_in_includes": 0,
      "filled_from_current_tweets": 0,
      "filled_from_cache": 0,
      "fetched_by_detail": 1,
      "self_fetched_by_detail": 0,
      "other_fetched_by_detail": 1,
      "missing_after": 0,
      "limited": false,
      "time_budget_exceeded": false,
      "time_budget_seconds": 125
    }
  },
  "errors": []
}
geo/place v2 sample
{
  "data": [
    {
      "id": "2068961229268267161",
      "text": "Tweet text",
      "author_id": "2001222910393126912",
      "geo": {
        "place_id": "5e02a0f0d91c76d2",
        "coordinates": null,
        "place": {
          "id": "5e02a0f0d91c76d2",
          "full_name": "Istanbul, Turkiye",
          "country": "Turkiye",
          "country_code": "TR",
          "place_type": "city",
          "name": "Istanbul"
        }
      },
      "public_metrics": {
        "retweet_count": 0,
        "reply_count": 0,
        "like_count": 0,
        "quote_count": 0,
        "bookmark_count": 0,
        "impression_count": 0,
        "total_engagement": 0
      },
      "attachments": { "media_keys": [], "poll_ids": [] },
      "context_annotations": []
    }
  ],
  "includes": {
    "users": [{ "id": "2001222910393126912", "username": "example_user" }],
    "media": [],
    "places": [
      {
        "id": "5e02a0f0d91c76d2",
        "full_name": "Istanbul, Turkiye",
        "country": "Turkiye",
        "country_code": "TR"
      }
    ],
    "polls": []
  },
  "meta": {
    "job_id": "job_example",
    "node_id": "node_example",
    "result_count": 3,
    "collection_date": "2026-06-22T07:36:22.456261Z",
    "cost": 0.05
  },
  "errors": []
}

Error Format

HTTP 200 tek basina basari anlamina gelmez.
Legacy response icin success === true kontrol edilmeli. V2 response icin errors.length === 0 ve meta.result_count birlikte degerlendirilmelidir.
UNAUTHORIZED
Eksik/gecersiz API key. HTTP 401.
INVALID_TYPE
Desteklenmeyen type. HTTP 400.
COUNT_TOO_LARGE
user_tweets_fetch count > 3000. HTTP 400.
NODE_TIMEOUT
Queue, execution veya client sync timeout. Normalize response olarak doner.
UPSTREAM_UNAVAILABLE
Node upstream 503 benzeri hata ile tamamlandiysa kullanilir.
NO_AVAILABLE_NODE
Istenen capability icin online/active node yoksa HTTP 503.
QUOTA_EXCEEDED
API key saatlik request limitini doldurduysa HTTP 402.
error sample
{
  "data": [],
  "includes": {
    "tweets": [],
    "users": [],
    "media": [],
    "places": [],
    "polls": []
  },
  "meta": {
    "job_id": null,
    "node_id": null,
    "result_count": 0,
    "collection_date": "2026-08-12T18:04:34.887267Z",
    "cost": 0.0
  },
  "errors": [
    {
      "title": "Invalid Request",
      "detail": "Unsupported request type",
      "type": "https://api.x.com/2/problems/invalid-request",
      "parameter": "type"
    }
  ]
}

Queue ve Timeout Mantigi

Master job'u once queued olusturur. Node kapasitesi bosaldiginda managed node batch claim ile isi alir. Queue bekleme, node execution ve client sync timeout ayri hesaplanir.

QUEUE_WAIT_TIMEOUT
60 saniye. Job queued durumundayken execution timeout baslamaz.
NODE_EXECUTION_TIMEOUT
Taban 1500 saniye; baslanan her 3000 tweet blogu icin 1500 saniye. Split depth eksenlerinden biri 50'yi asarsa 300 saniye eklenir; tavan 7200.
timeout_seconds
60-7200 araliginda is bazli override. Node ayni dahili timeout degerini kullanir.
Partial checkpoint
Node timeout aninda veri toplanmissa is completed kalir; meta.limited=true ve stop_reason=execution_timeout ile kismi veri doner.
Rate-limit progress
ACCOUNT_RATE_LIMITED bilgilendirme kodudur; client isi iptal etmemelidir. Node uygun hesaba aninda rotate eder.
Rate-limit partial
Veri toplandiysa completed doner; meta.partial=true, meta.limited=true ve stop_reason sonucu aciklar.
RateLimitExhausted
Async istekte hic veri toplanamadan hesap havuzu tukenirse waiting_rate_limit olur; 900 saniye sonra kontrollu yeniden denenir.
Retry
Retryable hata processing -> retrying -> queued ilerler; arada terminal failed gosterilmez.
Rate-limit progress
Node rate-limit'i gorur gormez processing job error_message alanina hesap notunu yazar.
Cancel
POST /api/jobs/{job_id}/cancel calisan subprocess'i node tarafinda durdurur; final durum cancelled olur.
CLIENT_SYNC_TIMEOUT
240 saniye; count > 100 icin en az 600, count >= 1000 icin node timeout + 120 saniye. Cloudflare nedeniyle agir islerde async jobs kullanilir.
Late complete
Master timeout'u timed_out durumuna girer; gec sonuc late_completed / late_failed olur. Terminal failed/completed tekrar acilmaz.
stop_reason
requested_count_reached, cutoff_date_reached, execution_timeout, no_page_tweets, no_cursor, repeated_cursor, cursor_cycle, overlap_found_target_reached ve date_range_scan_limit_reached temel degerlerdir.
Timeline sonu
Istenen count'tan az sonuc tek basina partial degildir. no_page_tweets, no_cursor, repeated_cursor ve cursor_cycle sonucunda partial=false, limited=false doner.
Raw 500
Hedef raw 500 dondurmemek; hatalar normalize errors[] formatina alinmaktadir.
timeout policy
{
  "queue_wait_timeout": 60,
  "node_execution_timeout_base": 1500,
  "node_execution_timeout_rule": "1500 seconds per started 3000 tweets",
  "node_execution_timeout_depth_surcharge": "300 seconds when either split depth is above 50",
  "node_execution_timeout_max": 7200,
  "timeout_seconds_override": "60..7200",
  "client_sync_timeout": 240,
  "client_sync_timeout_for_large_user_tweets": 300,
  "client_sync_timeout_for_1000_plus_user_tweets": "node timeout + 120 seconds",
  "timeout_checkpoint": "completed partial + limited=true + stop_reason=execution_timeout",
  "late_complete_policy": "late_completed or late_failed; normal completed status is not overwritten"
}

Node Mimarisi

X1

10

worker / concurrency_limit

X2

10

worker / concurrency_limit

Toplam

20

aktif paralel kapasite

Model
Managed pull. Node public client tarafindan cagrilmaz.
Batch polling
/api/nodes/job/next?limit=N
Concurrency
Master node bazli concurrency_limit degerini enforce eder.
active_jobs
Node'un raporladigi sayi degil, DB'deki gercek processing count ile sync edilir.
Duplicate engeli
FOR UPDATE SKIP LOCKED ve assigned_node_id is null OR current node kuralı.
batch claim shape
GET /api/nodes/job/next?node_id=node_lzy7gico&token=NODE_TOKEN&limit=15

{
  "status": "assigned",
  "jobs": [
    {
      "id": "job_example",
      "target_username": "SinemasaYT",
      "job_type": "username_fetch",
      "priority": 1,
      "username": "SinemasaYT",
      "count": 5000,
      "_node_execution_timeout": 3000,
      "_orchestrator_execution_timeout": 3120
    }
  ]
}

Kapasite ve Performans

30 paralel local test
30/30 success, timeout 0, raw 500 0.
Toplam kapasite
25 paralel processing; fazlasi queue/wait davranisina girer.
Max global processing
25.
X1 max
10 processing.
X2 max
10 processing.
Agir is
count>=2001 her is 3 efektif slot tuketir; node basina ayni anda en fazla 3 agir is claim edilir.
Duplicate claim
0.
DB pool
QueuePool hatasi yok; final processing=0, queued=0, active_jobs=0.
Cloudflare 1010
Public WAF davranisidir; local backend stress testi production core kapasiteyi dogruladi.

Pricing / Cost ve Rate Limit

Formula
cost = max((result_count / 1000) * price_per_1000, min_cost)
User tweets
user_tweets_price_per_1000 = 0.50, user_tweets_min_cost = 0.05.
Search
search_results_price_per_1000 = 0.80, search_results_min_cost = 0.05.
3000 tweet example
max((3000 / 1000) * 0.50, 0.05) = 1.50.
20 search example
max((20 / 1000) * 0.80, 0.05) = 0.05.
Rate limit
API key rate_limit saatlik request guard'dir. Varsayilan 1000 istek/saat; yeni veya mevcut anahtarlar panelden 1-1.000.000 araliginda ayarlanabilir.
Usage counters
total_usage kümülatif token usage; rate limit icin kalici kilit mekanizmasi degildir.

JSON Export

Tamamlanmis job sonuclari archepolis.xyz uzerinden JSON dosyasi olarak indirilebilir. Panelde /dashboard/jobs/:id detay ekranindaki JSON indir butonu ayni endpointi kullanir.

Endpoint
GET /api/jobs/{job_id}/export
Auth
Dashboard session veya ilgili API key.
Content-Type
application/json; charset=utf-8
Dosya adi
tweets_{username}_{YYYYMMDD_HHMMSS}.json
Icerik
Job result_data JSON payload'i. Tweet listesi, includes ve node'dan gelen alanlar korunur.
json export
curl -L "https://archepolis.xyz/api/jobs/job_fcc2eacd71be64cf/export" \
  -H "X-API-Key: YOUR_API_KEY" \
  -OJ

# Response header:
# Content-Disposition: attachment; filename="tweets_celalyaziyor_20260812_180543.json"

TemizVeri Uyumlulugu

Default/legacy response formati korunur. V2 response sadece opt-in ile aktif olur. Eski client'lar X-Response-Format: v2 veya response_format: "v2" gondermedigi surece response shape degismez.

Ornek cURL Koleksiyonu

legacy user_tweets_fetch count=2
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_tweets_fetch",
    "params": {
      "username": "celalyaziyor",
      "count": 2
    }
  }'
legacy user_tweets_fetch count=3000
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_tweets_fetch",
    "params": {
      "username": "SinemasaYT",
      "count": 3000
    }
  }'
v2 user_tweets_fetch
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Response-Format: v2" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_tweets_fetch",
    "params": {
      "username": "moononleo",
      "count": 80
    }
  }'
search_fetch
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "search_fetch",
    "params": {
      "query": "from:Fenerbahce",
      "count": 20,
      "type": "Latest"
    }
  }'
geo search
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Response-Format: v2" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "search_fetch",
    "params": {
      "query": "place_country:TR",
      "count": 20,
      "type": "Latest"
    }
  }'
poll example: moononleo
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Response-Format: v2" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_tweets_fetch",
    "params": {
      "username": "moononleo",
      "count": 80
    }
  }'
since_id delta
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "user_tweets_fetch",
    "params": {
      "username": "celalyaziyor",
      "count": 100,
      "since_id": "2068000000000000000",
      "query_flag": "daily_sync"
    }
  }'
public tweet detail
curl "https://archepolis.xyz/2/tweets/2095223570918166647?self_reference_depth=100&other_reference_depth=100" \
  -H "X-API-Key: YOUR_API_KEY"
public user by username
curl https://archepolis.xyz/2/users/by/username/celalyaziyor \
  -H "X-API-Key: YOUR_API_KEY"
public users by usernames
curl "https://archepolis.xyz/2/users?usernames=celalyaziyor,SinemasaYT" \
  -H "X-API-Key: YOUR_API_KEY"
public user id tweets
curl "https://archepolis.xyz/2/users/44196397/tweets?max_results=100&self_reference_depth=100&other_reference_depth=100" \
  -H "X-API-Key: YOUR_API_KEY"
json export
curl -L "https://archepolis.xyz/api/jobs/job_fcc2eacd71be64cf/export" \
  -H "X-API-Key: YOUR_API_KEY" \
  -OJ

# Response header:
# Content-Disposition: attachment; filename="tweets_celalyaziyor_20260812_180543.json"
invalid type
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"not_real","params":{}}'
invalid key
curl -X POST https://archepolis.xyz/api/execute/ \
  -H "X-API-Key: INVALID_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"user_tweets_fetch","params":{"username":"celalyaziyor","count":2}}'

Guvenlik Notlari

API key zorunludur ve server-side saklanmalidir.

Node token public client'a verilmez; node endpointleri managed worker icindir.

DataUsers, cookie, proxy ve upstream auth bilgileri dokumanda veya client kodunda yer almaz.

Client tarafinda Authorization: Bearer yerine X-API-Key header'i kullanilir.

Admin / Dashboard

/dashboard/nodes
Node status, worker sayisi, active_jobs / concurrency_limit ve node yasam dongusu.
/dashboard/nodes/provision
Temiz Ubuntu kurulumu, sifreli hesap/proxy envanteri, kalici 400 hesaplik node havuzlari, kurulum gecmisi ve yeniden kurulum.
/dashboard/jobs
Queued, processing, completed, failed job gozlemi ve tamamlanmis sonuclar icin JSON export.
/dashboard/settings
Pricing, min cost ve default rate limit ayarlari.
/dashboard/docs
Panel ici kisa API dokumantasyonu.

Worker kontrolu

X1 10, X2 10 worker ile izlenir.

Queue gozlemi

Processing ve queued sayilari DB state ile takip edilir.

Uyumluluk

Legacy ve V2 formatlar ayridir.

Dogrulama Notu

Son canli dogrulamalar
Legacy celalyaziyor count=2, TemizVeri default count=2, V2 moononleo count=80 ve V2 place_country:TR count=20 lokal backend uzerinden HTTP 200 ile dogrulandi. X1 10 ve X2 10 worker kapasitesiyle yapilan routing testlerinde duplicate claim ve raw 500 gorulmedi.