SDK Go per la conversione file#
github.com/conversionapi/go-sdk è il client EnConvert ufficiale per Go 1.21 e successivi. Si importa come package enconvert e non porta con sé alcuna dipendenza di terze parti: tutto gira su net/http, encoding/json e mime/multipart. Dodici metodi sul client coprono conversione file, rendering di URL e batch su interi siti (DOCX in PDF, HEIC in WebP, URL in PDF, URL in Markdown), e il namespace client.V2 aggiunge ventitré metodi di web intelligence per percepire, scoprire, cercare, distillare, ingerire e sorvegliare pagine. Ogni chiamata accetta un context.Context come primo argomento, così cancellazioni e scadenze restano nelle tue mani.
github.com/conversionapi/go-sdk · Package: enconvert · Sorgente: conversionapi/go-sdk · Go: 1.21+ · Dipendenze: nessuna
Installazione#
go get github.com/conversionapi/go-sdk
Il percorso del modulo finisce in go-sdk ma il package si chiama enconvert, quindi importalo con un nome esplicito: import enconvert "github.com/conversionapi/go-sdk".
Guida rapida#
package main
import (
"context"
"fmt"
"log"
"os"
enconvert "github.com/conversionapi/go-sdk"
)
func main() {
client, err := enconvert.New(os.Getenv("ENCONVERT_API_KEY"))
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
result, err := client.ConvertURLToPDF(ctx, "https://example.com", enconvert.URLToPDFOptions{SaveTo: "page.pdf"})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Filename, result.PresignedURL)
}
New restituisce un errore solo quando la chiave API è vuota; vedi Configurazione per le opzioni funzionali. Leggere una pagina come dovrebbe farlo un agente, con un punteggio di qualità allegato, è una sola chiamata sul namespace V2:
op, err := client.V2.Perceive(ctx, "https://example.com", enconvert.PerceiveOptions{
Outputs: []enconvert.PerceiveOutputName{enconvert.PerceiveOutputMarkdown},
})
fmt.Println(op.Outputs["markdown"].URL, *op.RenderQuality) // ad es. 0.93
Ogni frammento qui sotto presuppone un client e un ctx costruiti esattamente così.
Cosa espone il client#
Dodici metodi pendono da *enconvert.Client e corrispondono 1:1 agli endpoint REST. Le opzioni si passano sempre come valore struct, mai come puntatore, quindi il valore zero (enconvert.URLToPDFOptions{}) significa "tutti i default", e numeri e booleani facoltativi sono ovunque campi puntatore: usa gli helper enconvert.Int, enconvert.Bool, enconvert.Float64 ed enconvert.String invece di una variabile locale usa e getta.
| Metodo | Endpoint | Restituisce |
|---|---|---|
ConvertURLToPDF(ctx, url, opts) |
POST /v1/convert/url-to-pdf |
ConversionResult |
ConvertURLToScreenshot(ctx, url, opts) |
POST /v1/convert/url-to-screenshot |
ConversionResult |
ConvertURLToMarkdown(ctx, url, opts) |
POST /v1/convert/url-to-markdown |
ConversionResult |
ConvertImage(ctx, file, opts) |
POST /v1/convert/{from}-to-{to} |
ConversionResult |
ConvertDocument(ctx, file, opts) |
POST /v1/convert/{from}-to-{to} |
ConversionResult |
ConvertToMarkdown(ctx, file, opts) |
POST /v1/convert/anything-to-markdown |
ConversionResult |
ConvertToPDF(ctx, file, opts) |
POST /v1/convert/anything-to-pdf |
ConversionResult |
ConvertWebsiteToPDF(ctx, url, opts) |
POST /v1/convert/website-to-pdf |
BatchSubmission |
ConvertWebsiteToScreenshot(ctx, url, opts) |
POST /v1/convert/website-to-screenshot |
BatchSubmission |
GetJobStatus(ctx, jobID) |
GET /v1/convert/status/{jobID} |
JobStatus |
GetBatchStatus(ctx, batchID) |
GET /v1/convert/batch/{batchID} |
BatchStatus |
WaitForBatch(ctx, batchID, opts) |
GET /v1/convert/batch/{batchID} (con polling) |
BatchStatus |
client.V2 contiene altri ventitré metodi distribuiti su sei gruppi di capacità:
| Gruppo | Metodi | Percorso base |
|---|---|---|
| Perceive | Perceive, PerceiveDirect, GetPerceiveOperation, DownloadPerceiveArtifact, PerceiveBatch, GetPerceiveBatch |
/v2/perceive |
| Discover | Discover |
/v2/discover |
| Lookup | Lookup |
/v2/lookup |
| Distill | Distill |
/v2/distill |
| Ingest | Ingest, IngestFiles, GetIngestJob, ListIngestJobs, CancelIngestJob, RetryIngestWebhook, GetWebhookSecret, RotateWebhookSecret |
/v2/ingest |
| Watch | CreateWatcher, ListWatchers, GetWatcher, GetWatcherSnapshots, UpdateWatcher, DeleteWatcher |
/v2/watch |
Conversione file#
Gli upload accettano qualsiasi FileSource: enconvert.FilePath("report.docx") per un percorso su disco (il nome base determina il formato di input e il tipo MIME), enconvert.FileBytes(buf) per byte grezzi senza nome (caricati come upload.bin, application/octet-stream), oppure enconvert.FileInput{Data: buf, Filename: "report.docx"} per byte grezzi con un nome file esplicito e un ContentType facoltativo.
ConvertURLToPDF#
Esegue il rendering in PDF di qualsiasi URL raggiungibile.
result, err := client.ConvertURLToPDF(ctx, "https://example.com", enconvert.URLToPDFOptions{
SinglePage: enconvert.Bool(false),
PDFOptions: &enconvert.PDFOptions{PageSize: "A4", Orientation: "landscape"},
URLRenderOptions: enconvert.URLRenderOptions{ViewportWidth: enconvert.Int(1440)},
SaveTo: "report.pdf",
})
| Opzione | Tipo | Default | Descrizione |
|---|---|---|---|
SaveTo |
string |
-- | Percorso locale su cui scrivere il PDF in streaming. Le directory superiori vengono create per te. |
SinglePage |
*bool |
true |
true produce una sola pagina continua. false impagina usando PDFOptions.PageSize. |
PDFOptions |
*PDFOptions |
-- | Dimensione pagina, orientamento, margini, scala, scala di grigi, intestazione, piè di pagina. Vedi Opzioni PDF. |
ViewportWidth, ViewportHeight |
*int |
1920, 1080 |
Dimensione del viewport del browser in pixel. |
LoadMedia |
*bool |
true |
Attende immagini e video prima della cattura. |
EnableScroll |
*bool |
true |
Scorre dall'alto in basso per far scattare i lazy loader. |
OutputFilename |
string |
automatico | Sovrascrive il nome file generato. |
Auth |
*HTTPBasicAuth |
-- | Credenziali HTTP Basic per pagine dietro un login. |
Cookies, Headers |
[]BrowserCookie, map[string]string |
-- | Cookie iniettati prima del rendering (massimo 50) e header di richiesta aggiuntivi (massimo 20, quelli hop-by-hop vengono rifiutati). |
Tutto quello che va da ViewportWidth in giù vive sulla struct URLRenderOptions incorporata, condivisa da ogni metodo basato su URL.
Auth con un header Authorization. L'API rifiuta il conflitto invece di indovinare quale dei due intendevi.
ConvertURLToScreenshot e ConvertURLToMarkdown#
Cattura un PNG di qualsiasi URL, oppure estrae Markdown GitHub-Flavored pulito con frontmatter YAML (titolo, descrizione, url, link, immagini). Il convertitore Markdown rimuove navigazione, piè di pagina, pubblicità e script, e mantiene il corpo principale dell'articolo.
shot, err := client.ConvertURLToScreenshot(ctx, "https://example.com", enconvert.URLToScreenshotOptions{
URLRenderOptions: enconvert.URLRenderOptions{ViewportWidth: enconvert.Int(1440)},
SaveTo: "shot.png",
})
article, err := client.ConvertURLToMarkdown(ctx, "https://example.com/article",
enconvert.URLToMarkdownOptions{SaveTo: "article.md"})
Entrambi accettano le stesse URLRenderOptions di ConvertURLToPDF, più SaveTo. Nessuno dei due accetta SinglePage o PDFOptions.
ConvertImage#
Converte tra jpeg, png, svg, heic e webp in qualsiasi direzione, oppure rasterizza un PDF in JPEG.
// Da un percorso
result, err := client.ConvertImage(ctx, enconvert.FilePath("photo.heic"),
enconvert.ConvertImageOptions{OutputFormat: "webp", SaveTo: "photo.webp"})
// Da byte già in memoria
buf, _ := os.ReadFile("photo.heic")
result, err = client.ConvertImage(ctx, enconvert.FileInput{Data: buf, Filename: "photo.heic"},
enconvert.ConvertImageOptions{OutputFormat: "webp", SaveTo: "photo.webp"})
| Opzione | Tipo | Obbligatoria | Descrizione |
|---|---|---|---|
OutputFormat |
string |
Sì | jpeg, png, svg, heic o webp. jpg è accettato come alias di jpeg. |
SaveTo |
string |
-- | Percorso locale su cui scrivere il risultato in streaming. |
OutputFilename |
string |
-- | Sovrascrive il nome file generato. |
Il formato di input viene ricavato dall'estensione del nome file (.jpg, .jpeg, .png, .svg, .heic, .webp, .pdf). Le coppie non supportate falliscono in locale, prima di qualsiasi chiamata di rete, con un errore che elenca cosa è disponibile:
enconvert.ValidOutputsFor("pdf") // []string{"jpeg"}
enconvert.ValidOutputsFor("json") // []string{"csv", "toml", "xml", "yaml"}
ConvertDocument#
Converte documenti e formati dati. OutputFormat vale pdf quando lo lasci vuoto.
// docx in pdf
_, err := client.ConvertDocument(ctx, enconvert.FilePath("report.docx"),
enconvert.ConvertDocumentOptions{SaveTo: "report.pdf"})
// json in yaml
_, err = client.ConvertDocument(ctx, enconvert.FilePath("data.json"),
enconvert.ConvertDocumentOptions{OutputFormat: "yaml", SaveTo: "data.yaml"})
Input supportati: .doc, .docx, .xls, .xlsx, .ppt, .pptx, .html, .htm, .odt, .ods, .odp, .ots, .pages, .numbers, .md, .markdown, .csv, .json, .xml, .yaml, .yml, .toml.
| Opzione | Tipo | Default | Descrizione |
|---|---|---|---|
OutputFormat |
string |
"pdf" |
Formato di destinazione. yml, htm, md e jpg vengono normalizzati ai rispettivi nomi canonici. |
SaveTo |
string |
-- | Percorso locale su cui scrivere il risultato in streaming. |
OutputFilename |
string |
-- | Sovrascrive il nome file generato. |
PDFOptions |
*PDFOptions |
-- | Impostazioni di pagina. Hanno senso solo quando l'output è un PDF. |
Le 43 coppie implementate, esposte come mappa enconvert.ImplementedConversions, sono: json verso csv, toml, xml, yaml; xml verso csv, json; yaml verso json; csv verso json, xml; toml verso json; markdown verso html, pdf; html verso pdf; doc, excel, ppt, odt, ods, odp, ots, pages e numbers verso pdf; tutte e 20 le coppie ordinate tra jpeg, png, svg, heic, webp; e pdf verso jpeg.
EPUB non ha una coppia documenti dedicata. Passa i file .epub attraverso ConvertToPDF o ConvertToMarkdown.
ConvertToMarkdown#
Rileva automaticamente l'input lato server e restituisce Markdown pulito. È il mattone di base per l'ingestione RAG: PDF, DOCX, PPTX, XLSX, CSV, HTML, EPUB, TXT e MD, più i formati office legacy e ODF.
_, err := client.ConvertToMarkdown(ctx, enconvert.FilePath("handbook.pdf"),
enconvert.ConvertToMarkdownOptions{SaveTo: "handbook.md"})
ConvertToMarkdownOptions ha due campi, SaveTo e OutputFilename. Le immagini non sono supportate da questo endpoint, e su di esso non ci sono opzioni PDF. L'output conserva la gerarchia di intestazioni del documento, così un chunker semantico può dividere sulle intestazioni invece che su conteggi arbitrari di caratteri.
ConvertToPDF#
Rileva automaticamente l'input lato server e restituisce un PDF: office, ODF, Pages, Numbers, RTF, CSV, HTML, Markdown, testo semplice, immagini raster, SVG, EPUB, oppure un PDF esistente restituito così com'è per la normalizzazione.
_, err := client.ConvertToPDF(ctx, enconvert.FilePath("slides.pptx"),
enconvert.ConvertToPDFOptions{SaveTo: "slides.pdf"})
// Passthrough PDF, convertito in scala di grigi
_, err = client.ConvertToPDF(ctx, enconvert.FilePath("scan.pdf"), enconvert.ConvertToPDFOptions{
PDFOptions: &enconvert.PDFOptions{Grayscale: enconvert.Bool(true)},
SaveTo: "scan-gray.pdf",
})
PDFOptions.Grayscale. Ogni altro campo di geometria viene ignorato su anything-to-pdf. Usa ConvertDocument o ConvertURLToPDF quando ti servono dimensione pagina, orientamento, margini, scala, intestazioni o piè di pagina.
ConvertToPDFOptions ha tre campi: SaveTo, OutputFilename e PDFOptions.
ConvertWebsiteToPDF e ConvertWebsiteToScreenshot#
Individua ogni pagina di un sito, converte ciascuna in background e raccoglie tutto in un unico ZIP. Entrambi sono solo asincroni: restituiscono un BatchSubmission, e tu interroghi con GetBatchStatus oppure ti blocchi con WaitForBatch. Serve una chiave API privata con accesso al crawl.
batch, err := client.ConvertWebsiteToPDF(ctx, "https://example.com", enconvert.WebsiteToPDFOptions{
WebsiteConversionOptions: enconvert.WebsiteConversionOptions{CrawlMode: enconvert.CrawlModeSitemap},
})
status, err := client.WaitForBatch(ctx, batch.BatchID, enconvert.WaitForBatchOptions{SaveTo: "site.zip"})
fmt.Println(status.Completed, "of", status.Total, "pages converted")
| Opzione | Tipo | Default | Descrizione |
|---|---|---|---|
CrawlMode |
CrawlMode |
auto |
CrawlModeAuto, CrawlModeSitemap (solo sitemap.xml) o CrawlModeFull (sitemap più crawl BFS). |
IncludePatterns |
[]string |
-- | Fa il crawl solo degli URL che corrispondono a questi pattern, in modalità full crawl. |
ExcludePatterns |
[]string |
-- | Salta gli URL che corrispondono a questi pattern, in modalità full crawl. |
NotificationEmail |
string |
proprietario del progetto | Indirizzo avvisato quando il batch finisce. |
CallbackURL |
string |
-- | Webhook chiamato in POST quando il batch finisce. |
SinglePage |
*bool |
default del server | Solo PDF. Pagina continua o impaginata. |
PDFOptions |
*PDFOptions |
-- | Solo PDF. Applicate a ogni pagina. |
Anche tutto quello che sta su URLRenderOptions è accettato qui, e viene inviato per singola pagina solo quando lo imposti. WaitForBatchOptions accetta Interval (default 5 secondi), Timeout (default 30 minuti) e SaveTo. Sforare il timeout restituisce un *APIError con stato 504; un batch finito senza ZIP ne restituisce uno con stato 500. ConvertWebsiteToScreenshot è identico tolti SinglePage e PDFOptions, e produce uno ZIP di PNG.
Web intelligence (V2)#
Ogni lettura V2 porta con sé un punteggio RenderQuality da 0.0 a 1.0, esposto come *float64 su PerceiveResult, DistillItem, WatcherSnapshot e sul risultato del download diretto. Un punteggio basso significa che la pagina non si è renderizzata in modo pulito: una pagina di sfida, un muro dei cookie, uno shell SPA vuoto, un errore HTTP. Il contenuto torna comunque, segnalato, insieme a una mappa Deductions che nomina ogni penalità scattata e a uno slice Warnings, così una lettura sbagliata non entra mai di nascosto nel contesto del tuo agente. Tutti i metodi V2 richiedono una chiave API privata; le chiavi pubbliche vengono rifiutate. Usa il punteggio come filtro prima di fidarti di qualsiasi cosa:
if op.RenderQuality != nil && *op.RenderQuality < 0.6 {
log.Printf("low quality read of %s: %v", op.URL, op.Deductions)
}
Perceive#
Esegue il rendering di un URL negli artefatti che richiedi. Sincrono, con URL degli artefatti firmati per 15 minuti.
op, err := client.V2.Perceive(ctx, "https://example.com", enconvert.PerceiveOptions{
Outputs: []enconvert.PerceiveOutputName{enconvert.PerceiveOutputMarkdown, enconvert.PerceiveOutputStructured},
Extract: []enconvert.PerceiveExtractName{enconvert.PerceiveExtractTables, enconvert.PerceiveExtractMetadata},
Viewport: &enconvert.PerceiveViewport{Width: enconvert.Int(1440)},
})
fmt.Println(op.OperationID, op.Outputs["markdown"].URL, op.Structured, op.ExtractionTier)
// Rifirma gli URL degli artefatti più tardi
again, err := client.V2.GetPerceiveOperation(ctx, op.OperationID)
| Opzione | Tipo | Default | Descrizione |
|---|---|---|---|
Outputs |
[]PerceiveOutputName |
markdown, structured |
markdown, html_cleaned, html_raw, screenshot, screenshot_full_page, pdf, links, images, structured. |
Extract |
[]PerceiveExtractName |
-- | tables, prices, contacts, metadata, main_content, headings, structured_data, technologies, all. |
Schema |
map[string]any |
-- | Schema JSON per l'estrazione strutturata tramite il tier LLM. |
WaitFor, WaitTimeoutMs |
string, *int |
30000 ms |
Un selettore CSS, facoltativamente con prefisso css:, oppure js:<expr>, e il relativo budget (da 0 a 60000). |
JSCode |
string |
-- | JavaScript eseguito dopo la navigazione, massimo 20000 caratteri. |
Viewport |
*PerceiveViewport |
1920 x 1080 | Width da 320 a 3840, Height da 240 a 2160. |
Headers, Cookies, Auth |
map[string]string, []BrowserCookie, *HTTPBasicAuth |
-- | Header di richiesta, cookie iniettati, credenziali HTTP Basic. |
CacheMode |
PerceiveCacheMode |
enabled |
enabled (cache di 1 ora), bypass, refresh. |
PDFOptions |
*PDFOptions |
-- | Ha senso solo quando Outputs include pdf. |
BlockResources |
[]PerceiveResourceType |
-- | image, media, font, stylesheet, script, xhr, fetch, websocket, manifest, other. |
RespectRobots, Mobile |
*bool |
default del server | Rispetta robots.txt; emula un dispositivo mobile. |
OnlyMainContent |
*bool |
true |
Rimuove navigazione, header, footer e banner dei cookie dall'artefatto markdown e dall'estratto main_content. Imposta false per la pagina intera. |
DirectDownload |
*bool |
false |
Trasmette byte grezzi invece di una busta JSON. Preferisci PerceiveDirect. |
ProxyURL, Geolocation e ActionChain sono accettate dalla struct Go e serializzate, ma al momento il server risponde 422 per tutte e tre. Lasciale non impostate.
Trasmettere un singolo artefatto direttamente su disco salta la busta JSON. PerceiveDirect verifica in locale che tu abbia chiesto esattamente un output che produca un artefatto:
direct, err := client.V2.PerceiveDirect(ctx, "https://example.com", enconvert.PerceiveOptions{
Outputs: []enconvert.PerceiveOutputName{enconvert.PerceiveOutputPDF},
})
os.WriteFile(direct.Filename, direct.Content, 0o644)
// Riscarica più tardi un artefatto salvato. Passa "" quando l'operazione ne ha prodotto uno solo.
saved, err := client.V2.DownloadPerceiveArtifact(ctx, direct.OperationID, enconvert.PerceiveOutputPDF)
PerceiveDirectResult porta con sé Content, ContentType, Filename, OperationID, ObjectKey, CacheHit, RenderQuality, SourceStatusCode, ContentHash e WarningsCount, tutti letti dagli header della risposta. Un *APIError con 410 da DownloadPerceiveArtifact significa che l'artefatto è uscito dalla sua finestra di conservazione.
I batch accettano fino a 1000 URL con un unico blocco di opzioni condivise. I batch piccoli finiscono inline; quelli più grandi tornano queued, quindi interroga GetPerceiveBatch finché Status non è PerceiveBatchStatusCompleted e leggi Zip o Items:
batch, err := client.V2.PerceiveBatch(ctx, []string{"https://a.example", "https://b.example"},
enconvert.PerceiveBatchOptions{OutputMode: enconvert.PerceiveBatchOutputZip})
done, err := client.V2.GetPerceiveBatch(ctx, batch.JobID)
OutputMode è PerceiveBatchOutputManifest (predefinito) o PerceiveBatchOutputZip. DirectDownload viene rifiutato con 422 sui batch.
Discover#
Elenca gli URL di un sito a partire dalla sua sitemap, da un crawl HTTP o da entrambi. Non viene avviato alcun browser, quindi è veloce ed economico.
found, err := client.V2.Discover(ctx, "https://example.com", enconvert.DiscoverOptions{
Mode: enconvert.DiscoverModeHybrid, MaxURLs: enconvert.Int(200), ExcludePatterns: []string{"/tag/"},
})
fmt.Println(found.Total, found.Truncated, found.Sources)
| Opzione | Tipo | Default | Descrizione |
|---|---|---|---|
Mode |
DiscoverMode |
hybrid |
DiscoverModeSitemap, DiscoverModeCrawl o DiscoverModeHybrid (sitemap più crawl HTTP). |
MaxURLs, MaxDepth |
*int |
100, 2 |
Da 1 a 1000 URL, profondità del crawl da 1 a 5. |
IncludePatterns, ExcludePatterns |
[]string |
-- | Prima allowlist e poi denylist di espressioni regolari, semantica re.search, massimo 50 ciascuna. |
SameDomainOnly |
*bool |
true |
Resta sul dominio dell'URL di partenza. |
RespectRobots |
*bool |
default del server | Rispetta robots.txt. |
DiscoverResult ti dà URL, Mode, Total, URLs, PagesCrawled, Truncated, RobotsRespected, Sources (conteggi grezzi per sorgente prima della deduplicazione) e Warnings.
Lookup#
Ricerca web categorizzata, con la possibilità di renderizzare i primi risultati nello stesso round trip.
search, err := client.V2.Lookup(ctx, "best static site generators", enconvert.LookupOptions{
Category: enconvert.LookupCategoryWeb, NumResults: enconvert.Int(10), PerceiveTop: enconvert.Int(3),
})
for _, hit := range search.Results {
fmt.Println(hit.Position, hit.Title, hit.URL)
if hit.Perceive != nil {
fmt.Println(hit.Perceive.Outputs["markdown"].URL)
}
}
| Opzione | Tipo | Default | Descrizione |
|---|---|---|---|
Category |
LookupCategory |
web |
web, news, images, scholar, patents, maps. |
Country, Locale |
string |
-- | Codice paese gl di Google (us, in) e lingua dell'interfaccia hl (en). |
TimeFilter |
LookupTimeFilter |
-- | hour, day, week, month, year. |
NumResults, Page |
*int |
10, 1 |
Da 1 a 100 risultati, pagina da 1 a 10. |
Location |
string |
-- | Località in testo libero, per esempio Austin, Texas. |
Autocorrect |
*bool |
true |
Lascia che il provider corregga i refusi nella query. |
PerceiveTop |
*int |
0 |
Da 0 a 10. Esegue un render completo del browser sui primi N URL dei risultati e allega ciascun PerceiveResult inline. |
LookupResult porta con sé anche AnswerBox, KnowledgeGraph, PerceiveOperationIDs e Warnings.
Distill#
Estrazione strutturata guidata da uno schema. Fornisci esattamente uno tra URLs (massimo 50) e DiscoverFrom; Schema è sempre obbligatorio. Entrambe le regole vengono controllate in locale prima che parta qualsiasi richiesta.
extraction, err := client.V2.Distill(ctx, enconvert.DistillOptions{
URLs: []string{"https://example.com/pricing"},
Schema: map[string]any{"plans": "list of plan names with monthly prices"},
CSSSchema: &enconvert.CSSSchema{
BaseSelector: ".plan-card",
Fields: []enconvert.CSSField{
{Name: "name", Type: enconvert.CSSFieldText, Selector: "h3"},
{Name: "price", Type: enconvert.CSSFieldText, Selector: ".price"},
},
},
})
first := extraction.Results[0]
fmt.Println(first.Data, first.ExtractionTier, first.FieldsFromCSS, first.FieldsFromLLM)
Il CSSSchema facoltativo gira per primo e risponde a tutto ciò che può con semplici selettori; solo i campi che mancano vengono escalati al tier LLM, ed ExtractionTier riporta quali tier hanno effettivamente risposto (css, llm, mixed o none). CSSField.Type è uno tra text, attribute, html, regex, nested, list o nested_list, annidabile fino a 5 livelli di profondità.
Scambia URLs con DiscoverFrom per scoprire e poi distillare in un'unica chiamata. DistillDiscoverFrom accetta URL, Mode (default hybrid) e MaxPages (da 1 a 50, default 10, che limita sia la scoperta sia la distillazione):
_, err = client.V2.Distill(ctx, enconvert.DistillOptions{
DiscoverFrom: &enconvert.DistillDiscoverFrom{URL: "https://example.com", MaxPages: enconvert.Int(10)},
Schema: map[string]any{"title": "page title", "summary": "one-line summary"},
})
Ingest#
Trasforma un sito, un elenco di URL o una pila di documenti caricati in JSONL suddiviso in chunk e pronto per RAG. Sempre asincrono.
job, err := client.V2.Ingest(ctx, enconvert.IngestOptions{
Mode: enconvert.IngestModeSitemap,
URL: "https://docs.example.com",
MaxPages: enconvert.Int(100),
Chunk: &enconvert.IngestChunkOptions{MaxWords: enconvert.Int(512), SentenceOverlap: enconvert.Int(1)},
WebhookURL: "https://my.app/hooks/enconvert",
})
status, err := client.V2.GetIngestJob(ctx, job.JobID)
if status.Status == enconvert.IngestStatusCompleted {
fmt.Println(status.TotalChunks, status.OutputURL)
}
| Opzione | Tipo | Default | Descrizione |
|---|---|---|---|
Mode |
IngestMode |
urls |
IngestModeURLs, IngestModeSitemap, IngestModeCrawl, IngestModeFiles. |
URL |
string |
-- | URL di partenza. Obbligatorio per sitemap e crawl, vietato per urls. |
URLs |
[]string |
-- | URL espliciti, massimo 1000. Obbligatori per urls, vietati altrimenti. |
MaxPages, MaxDepth |
*int |
50, 2 |
Limite di scoperta da 1 a 1000 per sitemap e crawl, profondità da 1 a 5. |
SameDomainOnly |
*bool |
true |
Resta sul dominio dell'URL di partenza. |
IncludePatterns, ExcludePatterns |
[]string |
-- | Allowlist di espressioni regolari, poi denylist. |
RespectRobots |
*bool |
default del server | Rispetta robots.txt. |
WaitFor, WaitTimeoutMs |
string, *int |
30000 ms |
Selettore o espressione js: attesa per ogni pagina, e il relativo budget (da 0 a 60000). |
Chunk |
*IngestChunkOptions |
-- | MaxWords da 32 a 4000, default 512. SentenceOverlap da 0 a 10, default 1. |
WebhookURL |
string |
-- | Webhook di completamento, firmato in HMAC. |
Le regole su modalità e URL qui sopra vengono applicate lato client: Ingest restituisce un semplice errore Go, non un round trip verso l'API, se invii URLs con Mode: IngestModeSitemap.
I file caricati percorrono la stessa pipeline e lo stesso ciclo di vita del job:
fileJob, err := client.V2.IngestFiles(ctx,
[]enconvert.FileSource{enconvert.FilePath("handbook.pdf"), enconvert.FilePath("notes.docx")},
enconvert.IngestFilesOptions{Chunk: &enconvert.IngestChunkOptions{MaxWords: enconvert.Int(512)}})
Sono accettati PDF, DOCX, PPTX, XLSX, CSV, HTML, EPUB, TXT e MD, e file office legacy o ODF; serve almeno un file. Gestione dei job e impianto dei webhook:
list, err := client.V2.ListIngestJobs(ctx, enconvert.V2ListOptions{Limit: enconvert.Int(20)})
canceled, err := client.V2.CancelIngestJob(ctx, job.JobID) // idempotente
secret, err := client.V2.GetWebhookSecret(ctx) // Secret, SignatureHeader, SignatureScheme, ...
rotated, err := client.V2.RotateWebhookSecret(ctx) // le vecchie firme smettono subito di verificare
retry, err := client.V2.RetryIngestWebhook(ctx, job.JobID)
RetryIngestWebhook risponde 409 quando il job non è completato e 400 quando non ha alcun webhook configurato. V2ListOptions accetta Skip e Limit (da 1 a 100, default 20).
Watch#
Riesegue il rendering di una pagina a cadenza fissa e ti avvisa quando cambia.
watcher, err := client.V2.CreateWatcher(ctx, "https://example.com/pricing", enconvert.WatchCreateOptions{
FrequencyMinutes: enconvert.Int(60),
DiffMode: enconvert.WatchDiffAuto,
WebhookURL: "https://my.app/hooks/changes",
})
history, err := client.V2.GetWatcherSnapshots(ctx, watcher.WatcherID, enconvert.SnapshotListOptions{Limit: enconvert.Int(10)})
for _, snap := range history.Snapshots {
fmt.Println(snap.CheckedAt, snap.HasChanges, snap.ChangeCount, snap.Changes)
}
| Opzione | Tipo | Default | Descrizione |
|---|---|---|---|
FrequencyMinutes |
*int |
60 |
Da 60 a 43200. Il limite minimo di un'ora è rigido. |
DiffMode |
WatchDiffMode |
auto |
WatchDiffAuto, WatchDiffText, WatchDiffStructured, WatchDiffTables, WatchDiffMetadata. |
TrackFields |
map[string]any |
-- | Sottoinsieme di campi o selettori passato al motore di diff. |
WebhookURL, NotifyEmail |
string, *bool |
--, true |
Webhook di cambiamento firmato in HMAC, e se inviare un'email al proprietario del progetto. |
// Un puntatore alla stringa vuota azzera il webhook; nil lo lascia com'è.
_, err = client.V2.UpdateWatcher(ctx, watcher.WatcherID, enconvert.WatcherUpdate{
Status: enconvert.WatcherStatusPaused, WebhookURL: enconvert.String(""),
})
_, err = client.V2.DeleteWatcher(ctx, watcher.WatcherID) // soft delete, idempotente
UpdateWatcher richiede almeno un campo e restituisce un semplice errore Go se gli passi una struct vuota. Status accetta solo WatcherStatusActive o WatcherStatusPaused; l'eliminazione passa da DeleteWatcher, che restituisce il watcher marcato come eliminato con stato deleted. ListWatchers e GetWatcher completano il gruppo.
WatcherSnapshot.Changes è uno slice di mappe grezze prelevate dalla pagina sorvegliata. Applica l'escape ai valori prima di renderizzarli da qualsiasi parte.
Opzioni PDF#
PDFOptions è condivisa da ConvertURLToPDF, ConvertDocument, ConvertWebsiteToPDF, PerceiveOptions e (solo per Grayscale) ConvertToPDF. Vengono inviati solo i campi che imposti.
opts := &enconvert.PDFOptions{
PageSize: "A4",
Orientation: "landscape",
Margins: &enconvert.PDFMargins{Top: enconvert.Float64(10), Bottom: enconvert.Float64(10)},
Scale: enconvert.Float64(0.9),
Footer: &enconvert.PDFHeaderFooter{Content: "Confidential", Height: enconvert.Float64(20)},
}
| Campo | Tipo | Descrizione |
|---|---|---|
PageSize |
string |
"A4", "A3", "Letter", "Legal" e simili. |
PageWidth, PageHeight |
*float64 |
Impostali entrambi insieme per prevalere su PageSize. |
Orientation |
string |
"portrait" o "landscape". Il valore predefinito è verticale. |
Margins |
*PDFMargins |
Top, Bottom, Left, Right, ciascuno un *float64 in millimetri. Tutti e quattro facoltativi. |
Scale |
*float64 |
Scala di rendering, per esempio 0.9 per il 90%. |
Grayscale |
*bool |
Post-elabora il PDF convertendolo in scala di grigi. |
Header, Footer |
*PDFHeaderFooter |
Ciascuno ha Content (massimo 2000 caratteri) e Height. |
Gestione degli errori#
Go non ha classi di eccezione, quindi ogni errore dell'API è un unico tipo concreto, *enconvert.APIError, più tre predicati. Error() viene reso come "[<status>] <message>".
result, err := client.ConvertURLToPDF(ctx, "https://example.com", enconvert.URLToPDFOptions{})
switch {
case err == nil:
fmt.Println(result.PresignedURL)
case enconvert.IsAuthenticationError(err):
log.Println("invalid or missing API key")
case enconvert.IsRateLimitError(err):
log.Println("too many requests, back off and retry")
case enconvert.IsQuotaError(err):
log.Println("request rejected with 402")
default:
var apiErr *enconvert.APIError
if errors.As(err, &apiErr) {
log.Printf("api error [%d]: %s", apiErr.StatusCode, apiErr.Message)
} else {
log.Println(err) // errore di rete, cancellazione del context, validazione locale
}
}
| Controllo | Sollevato su | Codice di stato |
|---|---|---|
IsAuthenticationError(err) |
Chiave non valida, mancante o revocata | 401, 403 (entrambi registrati come 401) |
IsQuotaError(err) |
Qualsiasi risposta a cui l'API risponde con 402 |
402 |
IsRateLimitError(err) |
Limite di frequenza superato | 429 |
errors.As(err, &apiErr) |
Qualsiasi altro 4xx o 5xx | il codice effettivo |
Gli errori che non raggiungono mai la rete, come una coppia di conversione non supportata, una chiamata Distill con sia URLs sia DiscoverFrom, o una chiamata PerceiveDirect che chiede due artefatti, tornano come semplici valori error da errors.New o fmt.Errorf, non come *APIError. I codici di risposta sono catalogati nel riferimento sui codici di errore.
Recupero dei timeout#
I render lunghi di URL e le conversioni di documenti di grandi dimensioni possono superare il tetto di 60-120 secondi di un reverse proxy anche quando il job finisce senza problemi sul server. L'SDK ne esce con il polling, senza codice da parte tua:
- Prima di ogni conversione di un singolo file e di un singolo URL, il client genera un UUIDv4 e lo invia come
job_id. - Se quella richiesta torna con un codice
>= 500, il client passa silenziosamente aGET /v1/convert/status/{job_id}, interrogandolo ogni 3 secondi. - Su
successrestituisce il risultato. Sufailedrestituisce un*APIErrorcon stato500e il messaggio del server. - La scadenza del polling è di 5 minuti, dopodiché ottieni un
*APIErrorcon stato504e il messaggioConversion timed out.
ConversionResult.JobID è sempre valorizzato, anche quando il percorso sincrono è andato a buon fine e la risposta lo ha omesso, così puoi passarlo tu stesso a GetJobStatus:
status, err := client.GetJobStatus(ctx, result.JobID)
switch status.Status {
case enconvert.JobStatusSuccess:
fmt.Println(status.PresignedURL)
case enconvert.JobStatusFailed:
log.Println(status.Error)
}
ConvertWebsiteToPDF e ConvertWebsiteToScreenshot non hanno una riga di job per singola pagina da interrogare, quindi un 5xx lì emerge subito invece di essere riprovato. Nemmeno i metodi V2 usano il fallback sui job. Il polling gira dentro il context.Context che passi, quindi cancellare il context interrompe subito l'attesa.
Configurazione#
client, err := enconvert.New(os.Getenv("ENCONVERT_API_KEY"),
enconvert.WithTimeout(300*time.Second),
enconvert.WithBaseURL("https://api.enconvert.com"),
)
| Input del costruttore | Tipo | Default | Descrizione |
|---|---|---|---|
apiKey (primo argomento) |
string |
obbligatorio | Chiave API privata. New restituisce un errore quando è vuota. |
WithTimeout(d) |
time.Duration |
300 * time.Second |
Imposta Timeout sull'*http.Client interno, coprendo anche i download. |
WithBaseURL(u) |
string |
https://api.enconvert.com |
Override per un gateway self-hosted. Le barre finali vengono rimosse. |
Le scadenze per singola chiamata si sovrappongono al timeout del client tramite il context: avvolgilo con context.WithTimeout(context.Background(), 30*time.Second) e passa quello come primo argomento.
Il client si può condividere in sicurezza tra goroutine: contiene un *http.Client e nessuno stato mutabile per richiesta. Creane uno all'avvio e riusalo. Vedi autenticazione per i tipi di chiave e la rotazione.
Forma del risultato#
Le conversioni di un singolo file e di un singolo URL restituiscono un ConversionResult:
type ConversionResult struct {
PresignedURL string // URL di download firmato per l'output
ObjectKey string // chiave dell'oggetto nello storage
Filename string // nome file lato server
FileSize *int64 // byte, nil quando l'API lo omette
ConversionTimeSeconds *float64 // nil quando l'API lo omette
JobID string // sempre impostato dal client
}
Gli URL pre-firmati sono di breve durata. Passa SaveTo per far scrivere i byte su disco in streaming dall'SDK, oppure recupera tu stesso l'URL e archivia il file nel tuo bucket se ti serve un accesso a lungo termine. Il download deliberatamente non porta con sé la tua chiave API, dato che un URL pre-firmato si autentica da solo e inoltrare la chiave a un host di storage la esporrebbe.
Gli artefatti V2 arrivano come valori V2OutputArtifact indicizzati per nome di output, ciascuno con URL (pre-firmato per 15 minuti e rifirmato a ogni GET di stato), ObjectKey, SizeBytes, ContentType ed ExpiresIn (900 secondi per impostazione predefinita). PerceiveResult li avvolge insieme ai metadati di affidabilità: RenderQuality, StatusCode, Deductions, CacheHit, Warnings, ContentHash, URLFinal, Structured, ExtractionTier, Tokens, CostCents, DurationMs e OptionsEcho, che restituisce l'eco delle opzioni effettivamente rispettate dal server, con i segreti ridotti a booleani.
Sorgente e segnalazioni#
- Modulo e sorgente: github.com/conversionapi/go-sdk
- Versione: esposta a runtime come costante
enconvert.Version - Licenza: MIT, nessuna dipendenza di terze parti
Letture correlate: tutti gli SDK, panoramica V2, perceive, discover, lookup, distill, ingest, watch, panoramica degli endpoint, parametri e opzioni e la tua dashboard per le chiavi.
Domande frequenti#
Come converto file in Go?#
Esegui go get github.com/conversionapi/go-sdk, costruisci un client con enconvert.New(os.Getenv("ENCONVERT_API_KEY")), poi chiama un metodo tipizzato come ConvertDocument, ConvertImage o ConvertURLToPDF. Passa SaveTo nella struct delle opzioni e l'SDK scrive il file finito direttamente su quel percorso in streaming, creando le directory superiori quando serve.
Come converto un URL in PDF con Go?#
Chiama client.ConvertURLToPDF(ctx, url, enconvert.URLToPDFOptions{SaveTo: "page.pdf"}). Imposta SinglePage: enconvert.Bool(false) per impaginare invece di produrre una sola pagina continua, e passa PDFOptions per dimensione pagina, orientamento, margini, scala, scala di grigi, intestazioni e piè di pagina.
Come converto DOCX in PDF con Go?#
client.ConvertDocument(ctx, enconvert.FilePath("report.docx"), enconvert.ConvertDocumentOptions{SaveTo: "report.pdf"}). Il formato di output vale pdf per impostazione predefinita, quindi puoi lasciare OutputFormat vuoto. Lo stesso metodo gestisce input XLSX, PPTX, ODT, ODS, ODP, OTS, Pages, Numbers, HTML, Markdown, CSV, JSON, XML, YAML e TOML.
Come converto HEIC in WebP con Go?#
client.ConvertImage(ctx, enconvert.FilePath("photo.heic"), enconvert.ConvertImageOptions{OutputFormat: "webp", SaveTo: "photo.webp"}). Il formato di input viene letto dall'estensione del nome file, e tutte e 20 le coppie ordinate tra jpeg, png, svg, heic e webp funzionano allo stesso modo. Le coppie non supportate falliscono in locale prima che venga inviata qualsiasi richiesta.
L'SDK Go tira dentro dipendenze di terze parti?#
No. go.mod dichiara il modulo e un requisito minimo di Go 1.21, e nient'altro. Il client è costruito su net/http, encoding/json, mime/multipart e crypto/rand della libreria standard, quindi non aggiunge alcuna supply chain transitiva alla tua build.
Come estraggo una pagina web in Markdown pulito con Go?#
Due possibilità. client.ConvertURLToMarkdown restituisce Markdown GitHub-Flavored con frontmatter YAML ed è il percorso più semplice. client.V2.Perceive con Outputs: []enconvert.PerceiveOutputName{enconvert.PerceiveOutputMarkdown} ti dà lo stesso Markdown più un punteggio RenderQuality, Deductions, Warnings e la possibilità di aggiungere screenshot, link o estrazione strutturata nello stesso render.
Cosa significa la qualità del render e perché conviene controllarla?#
RenderQuality è un *float64 da 0.0 a 1.0 allegato a ogni lettura V2. Scende quando la pagina non si è renderizzata in modo onesto: una sfida anti-bot, un muro di login, un banner dei cookie sopra uno shell vuoto, o uno stato HTTP di errore. Il contenuto viene comunque restituito invece di essere inghiottito, quindi controlla il punteggio (e la mappa Deductions che nomina ogni penalità) prima di dare il testo in pasto a un modello.
Come imposto un timeout per singola richiesta o annullo una conversione in Go?#
Ogni metodo accetta un context.Context come primo argomento. Avvolgilo con context.WithTimeout o context.WithCancel per il controllo sulla singola chiamata; WithTimeout sul costruttore imposta il timeout di base del client HTTP per tutte le chiamate, incluso il download di un file con SaveTo.
Cosa succede quando una conversione lunga supera il timeout del proxy?#
L'SDK invia un job_id generato dal client con ogni conversione di un singolo file e di un singolo URL. Se la richiesta restituisce un codice >= 500, interroga GET /v1/convert/status/{job_id} ogni 3 secondi per un massimo di 5 minuti, restituendo il risultato su success e un *APIError su failed. Superare la scadenza produce un *APIError con stato 504. Gli invii di batch di interi siti saltano deliberatamente questo fallback.
Posso distribuire l'SDK Go dentro un client desktop o mobile?#
No. Si autentica con una chiave API privata, e gli endpoint V2 rifiutano senza appello le chiavi pubbliche. Tieni il client su un server che controlli e lascia che la tua app parli con quello. Vedi autenticazione per il modello delle chiavi.
Il client Go si può usare in sicurezza da più goroutine?#
Sì. *enconvert.Client avvolge un solo *http.Client e non mantiene alcuno stato mutabile per richiesta, quindi creane uno all'avvio e condividilo ovunque.