Ingest

POST /v2/ingest trasforma un sito — o un elenco esplicito di URL — in chunk pronti per il RAG ed emette un solo file JSONL che si carica direttamente in LangChain JSONLoader, LlamaIndex SimpleDirectoryReader o un import massivo in un vector-DB. Sostituisce lo stack in due fasi che altrimenti dovresti costruire: Firecrawl /crawl per scoprire ed estrarre i contenuti, più il tuo chunker per affettare il Markdown. EnConvert si occupa della discovery, del rendering headless-Chrome, del chunking consapevole delle intestazioni e dell'assemblaggio del JSONL in un solo job.

Ecco la chiamata utile più piccola. Fai il crawl di un sito e chunka ogni pagina che scopre:

curl -X POST https://api.enconvert.com/v2/ingest \
  -H "X-API-Key: sk_live_your_private_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "crawl",
    "url": "https://example.com/docs"
  }'

La risposta è il record del job, restituito con 202 Accepted. Nota che lo status è queued, e output_url è assente finché il job non si completa:

{
    "job_id": "ing_3f9a2c1b8e7d4a6f90b1c2d3e4f5a6b7",
    "status": "queued",
    "mode": "crawl",
    "pages_discovered": 0,
    "pages_processed": 0,
    "pages_failed": 0,
    "total_chunks": 0,
    "webhook_delivered": false,
    "created_at": "2026-06-24T09:14:02.118Z"
}

Ingest è sempre asincrono. Ogni pagina viene renderizzata in un browser reale, il che richiede 10–30 secondi per URL — ben oltre la finestra di richiesta di 300 secondi per qualsiasi job non banale. Quindi POST risponde 202 con un job_id, e un worker locale sul droplet svuota il job fuori banda. Fai il polling di GET /v2/ingest/{job_id} per i progressi, oppure registra un webhook_url per essere avvisato al completamento.

Vale la pena segnalarlo subito. /v2/ingest è un endpoint V2 con il proprio contatore di quota, ingest_pages. I piani di conversione V1 non includono alcun budget di ingest — serve un piano che includa V2 per chiamarlo. Viene addebitata una pagina per ogni URL il cui stage di render, chunk e JSONL si completa; le pagine che falliscono o vengono saltate non vengono addebitate. Vedi la pagina dei prezzi per i budget per livello, e la panoramica V2 per come i contatori V2 differiscono dalle conversioni V1.


Endpoints

Method Path Scopo
POST /v2/ingest Crea un job di ingest. Risponde 202 con un job_id.
GET /v2/ingest Elenco dei job di questo progetto, dal più recente, con paging skip/limit.
GET /v2/ingest/{job_id} Stato del ciclo di vita di un job, con un output_url appena firmato una volta completato.
DELETE /v2/ingest/{job_id} Annulla un job. Il worker vede lo status canceled e si ferma tra una pagina e l'altra.
POST /v2/ingest/{job_id}/retry-webhook Ri-firma e ri-invia in POST il webhook di completamento per un job completato.
GET /v2/ingest/webhook-secret Rivela il segreto di firma dei webhook del progetto (canale dashboard).
POST /v2/ingest/webhook-secret/rotate Ruota il segreto di firma. Le vecchie firme smettono di verificarsi immediatamente.

Content-Type: application/json su ogni POST.


Autenticazione

Autenticati con una chiave privata nell'header X-API-Key per le chiamate server-to-server. Questo è il percorso usato dagli esempi seguenti.

X-API-Key: sk_live_your_private_key

Funzionano anche le chiavi pubbliche con un token bearer JWT, usando lo stesso flusso di ogni altro endpoint — genera un token con la tua chiave pk_, poi invialo come Authorization: Bearer <token>. Il flusso completo, inclusi il domain locking e il refresh del token, è ne la guida all'autenticazione.

Ogni chiave API porta con sé una allowlist di endpoint consentiti. Se /v2/ingest non è nell'elenco della chiave, la richiesta viene rifiutata con 403. Una chiave con scope su /v2/ingest raggiunge comunque i job che ha creato — GET e DELETE /v2/ingest/{job_id} e POST /v2/ingest/{job_id}/retry-webhook sono sempre consentiti per un job_id (la forma ing_… viene confrontata in modo esplicito). L'endpoint di elenco statico e le due route di gestione webhook-secret non ereditano quel bypass; richiedono un token più ampio o con scope dashboard.


Come funziona l'ingest

Un job attraversa cinque fasi, tutte durevoli e a prova di riavvio. Se il processo worker si riavvia a metà job, il job viene ri-accodato all'avvio e riprende dalla pagina su cui si era fermato — le pagine già completate mantengono il loro output in staging e non vengono mai ri-renderizzate né ri-addebitate.

  1. Queue. POST valida la richiesta, esegue un veloce controllo di quota units=1 (il piano ha ingest abilitato e un po' di margine mensile), inserisce la riga del job e risponde 202. Nulla viene persistito se il gate di quota fallisce — un 402 non lascia alcuna riga dietro di sé.
  2. Discover. Per le modalità sitemap e crawl il worker esegue lo stesso passaggio di discovery di l'endpoint discover, limitato a max_pages, e applica lo screening SSRF all'URL seed. Per la modalità urls l'elenco esplicito viene deduplicato nell'ordine dato; nessuna discovery viene eseguita.
  3. Render and chunk. Ogni URL viene renderizzato attraverso il singleton headless Chrome condiviso — la stessa pipeline di rendering dietro l'endpoint perceive — poi l'HTML renderizzato viene convertito in fit-Markdown e affettato dal chunker consapevole delle intestazioni. I rendering vengono eseguiti in sequenza, una pagina alla volta.
  4. Stage. I chunk di ogni pagina vengono scritti in un oggetto JSONL per pagina nello storage, con chiave deterministica basata su (project, job, url). È questo che rende economico un riavvio: un job ripreso riutilizza le pagine in staging invece di ri-renderizzarle.
  5. Assemble. Una volta che ogni pagina è pronta, gli oggetti per pagina vengono concatenati nel v2-ingest/{job_id}.jsonl finale, gli oggetti di staging vengono eliminati, il job passa a completed e — se era impostato un webhook_url — scatta il webhook di completamento firmato.

Il contatore di quota viene ri-controllato per pagina dentro il worker, non solo al momento dell'invio. Un job crawl il cui conteggio di pagine è ignoto in partenza si ferma in modo pulito al tuo limite mensile: le pagine già renderizzate vengono addebitate e conservate, e le pagine rimanenti vengono marcate skipped invece di sforare la spesa.

I rendering di ingest sono privi di credenziali per progettazione. A differenza di /v2/perceive, non accetta auth, cookies o headers personalizzati — nulla di segreto viene persistito per il resume durevole, quindi lo stato del job su disco non porta mai con sé credenziali.


Parametri della richiesta

Sorgente e modalità

Parameter Type Default Descrizione
mode string "urls" urls, sitemap o crawl. Seleziona come viene costruito l'insieme di URL.
url string null URL seed per la modalità sitemap/crawl. Deve iniziare con http:// o https://. Massimo 2.048 caratteri. Richiesto per quelle modalità; rifiutato in modalità urls.
urls string[] null URL espliciti da ingerire in modalità urls. Non vuoto, massimo 1.000 voci, ciascuna http(s) e ≤ 2.048 caratteri. Richiesto per la modalità urls; rifiutato in modalità sitemap/crawl.

url e urls si escludono a vicenda — esattamente una sorgente. La modalità urls richiede urls; sitemap e crawl richiedono un url seed. Inviare quello sbagliato per la modalità è un 422.

Discovery (modalità sitemap / crawl)

Questi vengono inoltrati al passaggio di discovery e ignorati in modalità urls.

Parameter Type Default Descrizione
max_pages integer 50 Limite sugli URL scoperti e ingeriti. 1–1.000.
max_depth integer 2 Profondità dei link nel crawl a partire dal seed. 1–5.
same_domain_only boolean true Restringe la discovery al dominio del seed.
include_patterns string[] [] Pattern regex che un URL deve soddisfare per essere mantenuto. Massimo 50. Ciascuno viene compilato all'invio; un pattern errato è un 422.
exclude_patterns string[] [] Pattern regex che scartano un URL corrispondente. Massimo 50.
respect_robots boolean false Quando è true, un URL non consentito dal robots.txt del sito viene saltato.

Rendering

Parameter Type Default Descrizione
wait_for string null Dopo la navigazione, attende un selettore CSS o un'espressione JS prima di catturare. Massimo 1.024 caratteri.
wait_timeout_ms integer 30000 Per quanto tempo wait_for può attendere, in millisecondi. 0–60.000.

Nota. Ingest non accetta auth, cookies o headers. Se una pagina ha bisogno di credenziali per essere renderizzata, ingest è lo strumento sbagliato — usa l'endpoint perceive, che porta con sé l'intera superficie di richiesta autenticata, per quella singola pagina.

Chunking (oggetto chunk)

Parameter Type Default Vincoli Descrizione
max_words integer 512 32–4.000 Limite soft di parole per chunk. Consapevole delle intestazioni. I blocchi di codice e le tabelle pipe restano atomici e possono superarlo.
sentence_overlap integer 1 0–10 Frasi ripetute tra chunk di prosa consecutivi della stessa sezione. 0 disabilita l'overlap. L'overlap non attraversa mai un confine di intestazione.

Il chunker divide sulle intestazioni #, ## e ### — ogni chunk appartiene a esattamente una sezione e porta con sé il proprio percorso completo di intestazioni. Le intestazioni più profonde (##########) restano inline come contenuto. I blocchi di codice recintati e le tabelle Markdown non vengono mai divisi, anche quando un singolo blocco supera max_words; gli elementi di lista si dividono tra le voci, mai a metà voce.

Webhook

Parameter Type Default Descrizione
webhook_url string null Endpoint che riceve la callback di completamento firmata con HMAC. Massimo 2.048 caratteri. Lo schema viene controllato all'invio; lo screening SSRF avviene al momento della consegna, non dell'invio.

Response

POST, GET /v2/ingest/{job_id} e DELETE restituiscono tutti lo stesso oggetto IngestJobResponse.

Field Type Descrizione
job_id string ID opaco (ing_…). Usalo con gli endpoint GET/DELETE e citalo al supporto.
status string queued, discovering, processing, completed, failed o canceled.
mode string La modalità che hai inviato: urls, sitemap o crawl.
pages_discovered integer URL che il job ingerirà (l'elenco esplicito, o il risultato della discovery).
pages_processed integer URL il cui render → chunk → stage si è completato.
pages_failed integer URL che non sono riusciti a renderizzare o sono stati saltati (es. quota esaurita).
total_chunks integer Totale dei chunk scritti su tutte le pagine completate — corrisponde al conteggio di righe del JSONL.
output_url string URL di download pre-firmato per il JSONL finale. Presente solo quando status è completed; scade dopo 15 minuti.
error_message string Impostato quando status è failed (es. discovery rifiutata, tutte le pagine fallite).
webhook_url string Il target del webhook di completamento registrato per questo job, se presente.
webhook_delivered boolean true una volta che il webhook di completamento firmato ha ricevuto un 2xx.
created_at string Quando il job è stato creato (UTC).
completed_at string Quando il job ha raggiunto uno status terminale (UTC).
warnings string[] Note non fatali.

Nota. POST e il GET/DELETE per singolo job usano response_model_exclude_none, quindi i campi ancora null (come output_url prima del completamento) vengono omessi dal JSON anziché inviati come null.

La forma del record JSONL

Il file finale è JSON delimitato da newline. Ogni riga è un chunk:

{"id":"9f2b8c1ad4e5-0000","content":"Pricing is usage-based...","metadata":{"source_url":"https://example.com/pricing","title":"Pricing","headings_path":["Pricing","Plans"],"section":"Plans","word_count":118,"chunk_index":0}}
Field Type Descrizione
id string Deterministico per (source_url, chunk_index): <md5(url)[:12]>-<index:04d>. Una ri-esecuzione produce id identici.
content string Il testo del chunk recuperabile. Mappa su Document.page_content in LangChain.
metadata.source_url string La pagina da cui proviene il chunk.
metadata.title string Il <title> della pagina, con fallback sul primo <h1>, limitato a 512 caratteri.
metadata.headings_path string[] Il percorso h1 → h2 → h3 sotto cui si trova il chunk.
metadata.section string Il testo dell'intestazione più interna (l'ultima voce di headings_path).
metadata.word_count integer Conteggio di parole di content, delimitate da spazi bianchi.
metadata.chunk_index integer L'indice del chunk all'interno della sua pagina.

Il file è UTF-8, scritto con ensure_ascii=false, quindi l'unicode resta leggibile. Poiché content è una stringa di primo livello e metadata è un oggetto fratello, lo stesso file si carica tramite LangChain JSONLoader(content_key="content", json_lines=True), LlamaIndex SimpleDirectoryReader e qualsiasi import vector-DB orientato alle righe senza alcuna ristrutturazione.


Ciclo di vita del job e polling

Un job attraversa questi stati:

queued → discovering → processing → completed | failed | canceled
Status Significato
queued Accettato e in attesa del worker.
discovering Esegue il passaggio di discovery sitemap/crawl (solo sitemap/crawl).
processing Rendering e chunking delle pagine. pages_processed e total_chunks salgono in tempo reale.
completed Il JSONL finale è assemblato; output_url è firmato e pronto.
failed La discovery è stata rifiutata, oppure ogni pagina è fallita o è stata saltata. error_message spiega.
canceled Un DELETE ha raggiunto il job prima che terminasse.

Fai il polling dello status con il GET per singolo job. È in sola lettura — non consuma quota e ri-firma l'output_url dalla chiave dell'oggetto memorizzato a ogni chiamata:

curl https://api.enconvert.com/v2/ingest/ing_3f9a2c1b8e7d4a6f90b1c2d3e4f5a6b7 \
  -H "X-API-Key: sk_live_your_private_key"

Un job_id sconosciuto, o uno che appartiene a un progetto diverso, restituisce 404 — l'esistenza non viene mai rivelata tra progetti.

Elenco dei job

GET /v2/ingest restituisce i job di questo progetto dal più recente, con i query param skip e limit. limit ha default 20 ed è limitato a 100. La risposta porta un flag has_more invece di un conteggio totale:

curl "https://api.enconvert.com/v2/ingest?skip=0&limit=20" \
  -H "X-API-Key: sk_live_your_private_key"
{
    "jobs": [
        {
            "job_id": "ing_3f9a...",
            "status": "completed",
            "mode": "crawl",
            "pages_discovered": 42,
            "pages_processed": 41,
            "pages_failed": 1,
            "total_chunks": 1187,
            "output_url": "https://spaces.example.com/...signed...",
            "webhook_configured": true,
            "webhook_delivered": true,
            "created_at": "2026-06-24T09:14:02.118Z",
            "completed_at": "2026-06-24T09:31:55.402Z"
        }
    ],
    "skip": 0,
    "limit": 20,
    "has_more": false
}

Le righe dell'elenco riducono webhook_url a un booleano webhook_configured — l'elenco non rimanda mai l'endpoint grezzo nella tabella.

Annullamento di un job

DELETE /v2/ingest/{job_id} imposta lo status del job a canceled. Il worker legge quello status tra una pagina e l'altra e si ferma senza assemblare l'output. L'annullamento è idempotente e a prova di race: se l'assemblaggio è già stato confermato, il DELETE non corrisponde a nulla e il job viene restituito invariato come completed — un job concluso non viene mai riportato indietro a canceled.

curl -X DELETE \
  https://api.enconvert.com/v2/ingest/ing_3f9a2c1b8e7d4a6f90b1c2d3e4f5a6b7 \
  -H "X-API-Key: sk_live_your_private_key"

Webhook di completamento

Imposta webhook_url sul POST ed EnConvert invia un POST firmato con HMAC quando il job si completa. Il payload è JSON compatto, con chiavi ordinate:

{"job_id":"ing_3f9a...","output_url":"https://spaces.example.com/...signed...","pages_processed":41,"status":"completed","total_chunks":1187}

La consegna ritenta fino a tre volte dopo il primo tentativo, con ritardi di back-off di 1, 4 e 16 secondi — quattro POST nel caso peggiore. Ogni tentativo viene ri-firmato con un timestamp fresco, così una catena di retry lenta non va mai oltre la finestra di freschezza del consumer. Una risposta 2xx è un successo; un endpoint morto viene registrato come mancata consegna (e fa scattare un alert nella dashboard), non affossa mai un job altrimenti completato.

Il webhook_url viene sottoposto a screening SSRF al momento della consegna, non all'invio. Un URL che risolve a un indirizzo privato, di loopback o di metadata viene memorizzato in modo inerte e rifiutato solo quando EnConvert prova a inviarci un POST.

Verifica della firma

Ogni consegna porta due header:

Header Valore
X-Enconvert-Signature sha256=<hex> — l'HMAC-SHA256 di <timestamp>.<raw body>.
X-Enconvert-Timestamp Il timestamp in unix-seconds legato alla firma.

L'input di firma è il timestamp, un . letterale, poi il corpo grezzo della richiesta. Legare il timestamp nel MAC significa che un consumer che rifiuta i timestamp scaduti ottiene gratis la protezione dal replay — la finestra di freschezza di default è 300 secondi. Verifica nel tuo handler:

import hashlib
import hmac
import time

SECRET = "whsec_your_signing_secret"   # from GET /v2/ingest/webhook-secret
TOLERANCE_SECONDS = 300


def verify(raw_body: bytes, signature_header: str, timestamp_header: str) -> bool:
    if not signature_header or not timestamp_header:
        return False
    try:
        ts = int(timestamp_header)
    except ValueError:
        return False
    if abs(time.time() - ts) > TOLERANCE_SECONDS:
        return False  # replayed or badly skewed clock

    provided = signature_header.removeprefix("sha256=")
    expected = hmac.new(
        SECRET.encode("utf-8"),
        f"{ts}.".encode("utf-8") + raw_body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, provided)

Gestione del segreto di firma

GET /v2/ingest/webhook-secret rivela il segreto del progetto (creandolo alla prima chiamata) insieme ai nomi degli header e alla tolleranza di cui il tuo consumer ha bisogno. È sensibile ed esposto solo sul canale autenticato della dashboard:

{
    "secret": "whsec_...",
    "signature_header": "X-Enconvert-Signature",
    "timestamp_header": "X-Enconvert-Timestamp",
    "signature_scheme": "sha256",
    "replay_tolerance_seconds": 300,
    "rotated": false
}

POST /v2/ingest/webhook-secret/rotate emette un nuovo segreto e imposta rotated a true. Ogni firma calcolata con il segreto precedente smette di verificarsi nel momento in cui la rotazione viene confermata — ruota dopo un sospetto leak, poi aggiorna il tuo consumer.

Riconsegna di un webhook

Se il tuo endpoint era giù quando il job è terminato, POST /v2/ingest/{job_id}/retry-webhook ri-firma e ri-invia in POST con la stessa policy di retry:

curl -X POST \
  https://api.enconvert.com/v2/ingest/ing_3f9a.../retry-webhook \
  -H "X-API-Key: sk_live_your_private_key"
{
    "job_id": "ing_3f9a...",
    "delivered": true,
    "attempts": 1,
    "status_code": 200,
    "detail": "Delivered (HTTP 200)."
}

Restituisce 404 per un job_id sconosciuto o estraneo, 400 quando nessun webhook_url è configurato (o l'URL memorizzato ora risolve a un indirizzo privato/interno), e 409 quando il job non ha raggiunto completed.


Esempi di codice

curl — elenco esplicito di URL

curl -X POST https://api.enconvert.com/v2/ingest \
  -H "X-API-Key: sk_live_your_private_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "urls",
    "urls": [
      "https://example.com/docs/intro",
      "https://example.com/docs/quickstart",
      "https://example.com/docs/api"
    ]
  }'

curl — crawl con chunking e webhook

curl -X POST https://api.enconvert.com/v2/ingest \
  -H "X-API-Key: sk_live_your_private_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "crawl",
    "url": "https://example.com/docs",
    "max_pages": 200,
    "max_depth": 3,
    "include_patterns": ["/docs/"],
    "chunk": {"max_words": 700, "sentence_overlap": 2},
    "webhook_url": "https://your-app.example.com/hooks/ingest"
  }'

Python — invio, polling, download

import time

import requests

BASE = "https://api.enconvert.com"
HEADERS = {"X-API-Key": "sk_live_your_private_key"}

# 1. Submit (always 202).
job = requests.post(
    f"{BASE}/v2/ingest",
    headers=HEADERS,
    json={"mode": "crawl", "url": "https://example.com/docs", "max_pages": 100},
).json()
job_id = job["job_id"]

# 2. Poll until terminal.
while True:
    job = requests.get(f"{BASE}/v2/ingest/{job_id}", headers=HEADERS).json()
    if job["status"] in ("completed", "failed", "canceled"):
        break
    time.sleep(5)

# 3. Download the JSONL from its signed URL.
if job["status"] == "completed":
    jsonl = requests.get(job["output_url"]).text
    print(f"{job['total_chunks']} chunks across "
          f"{job['pages_processed']} pages")
    print(jsonl.splitlines()[0])

Node.js — invio e polling

const BASE = "https://api.enconvert.com";
const HEADERS = {
    "Content-Type": "application/json",
    "X-API-Key": "sk_live_your_private_key"
};

// 1. Submit.
const submit = await fetch(`${BASE}/v2/ingest`, {
    method: "POST",
    headers: HEADERS,
    body: JSON.stringify({
        mode: "crawl",
        url: "https://example.com/docs",
        max_pages: 100
    })
});
let job = await submit.json();

// 2. Poll until terminal.
while (!["completed", "failed", "canceled"].includes(job.status)) {
    await new Promise((r) => setTimeout(r, 5000));
    const poll = await fetch(`${BASE}/v2/ingest/${job.job_id}`, {
        headers: { "X-API-Key": HEADERS["X-API-Key"] }
    });
    job = await poll.json();
}

// 3. Download the JSONL.
if (job.status === "completed") {
    const jsonl = await fetch(job.output_url).then((r) => r.text());
    console.log(`${job.total_chunks} chunks`);
    console.log(jsonl.split("\n")[0]);
}

Gating del piano

L'ingest V2 è misurato dal proprio contatore, ingest_pages — separato dalle conversioni V1 e dagli altri contatori V2. Viene addebitata una pagina per ogni URL il cui stage di render, chunk e JSONL si completa; le pagine che falliscono o vengono saltate non vengono addebitate.

Il controllo al momento dell'invio è un veloce gate units=1: il tuo piano deve avere ingest abilitato, con un po' di margine mensile. Il vero limitatore di spesa è il controllo per pagina dentro il worker — un job crawl si ferma in modo pulito al tuo limite mensile e marca le pagine rimanenti skipped invece di sforarlo.

Gate Comportamento
Piano senza ingest abilitato 402 all'invio — passa a un piano che include V2.
Quota mensile ingest_pages esaurita 402 all'invio; oppure, se esaurita a metà job, le pagine rimanenti vengono marcate skipped.
Illimitato (enterprise / admin) Un limite di 0 con il flag abilitato significa nessun limite mensile.

MAX_PAGES_PER_JOB (1.000) è un tetto per richiesta che delimita un singolo job; non è il tuo budget mensile. La quota mensile ingest_pages è il vero limitatore di spesa. I numeri attuali per livello sono su la pagina dei prezzi; vedi anche come vengono misurate le operazioni perceive per il contatore V2 gemello.


Risposte di errore

Status Condizione
202 Accepted Il job è stato creato e accodato. Questo è l'esito normale del POST.
401 Unauthorized Chiave API / token JWT mancante o non valido.
402 Payment Required L'ingest non è nel tuo piano attuale, oppure la tua quota mensile ingest_pages è esaurita.
403 Forbidden /v2/ingest non è negli endpoint consentiti della chiave API.
404 Not Found job_id sconosciuto, o uno posseduto da un altro progetto.
409 Conflict retry-webhook chiamato su un job che non ha raggiunto completed.
400 Bad Request retry-webhook chiamato senza alcun webhook_url configurato, oppure il suo URL memorizzato ora risolve a un indirizzo privato/interno.
422 Unprocessable Entity La sorgente non corrisponde alla modalità (urls senza urls, o un url seed in modalità urls); un parametro è fuori range; oppure una regex di include_patterns/exclude_patterns non compila.
500 Internal Server Error Impossibile creare il job. Il messaggio include il job_id da citare al supporto.

Un fallimento di render a livello di pagina non fa fallire la richiesta né il job — incrementa pages_failed, deposita l'errore della pagina nella sua riga e il job continua. Un job fails solo quando la discovery viene rifiutata oppure ogni pagina fallisce o viene saltata. Il riferimento completo dei codici di stato è ne la guida ai codici di errore.


Limiti

Limite Valore
URL per richiesta in modalità urls 1.000
Lunghezza di url / di ciascuna voce urls 2.048 caratteri
max_pages (limite di discovery) 1–1.000
max_depth 1–5
include_patterns / exclude_patterns 50 ciascuno
Lunghezza di wait_for 1.024 caratteri
wait_timeout_ms 0–60.000 ms
chunk.max_words 32–4.000 (default 512)
chunk.sentence_overlap 0–10 (default 1)
Lunghezza di webhook_url 2.048 caratteri
Tetto di pagine per job (MAX_PAGES_PER_JOB) 1.000
limit dell'elenco GET /v2/ingest 1–100 (default 20)
Scadenza dell'output_url firmato 15 minuti
Tentativi di consegna del webhook 4 (iniziale + 3 retry)
Tolleranza di replay del webhook 300 secondi
ingest_pages mensili Dipende dal piano — vedi prezzi