Go SDK für Dateikonvertierung#
github.com/conversionapi/go-sdk ist der offizielle EnConvert-Client für Go 1.21 und neuer. Er wird als Paket enconvert importiert und bringt keine einzige Fremdabhängigkeit mit: Alles läuft auf net/http, encoding/json und mime/multipart. Zwölf Methoden am Client decken Dateikonvertierung, URL-Rendering und Batches für ganze Websites ab (DOCX zu PDF, HEIC zu WebP, URL zu PDF, URL zu Markdown), und der Namensraum client.V2 ergänzt dreiundzwanzig Methoden für Web-Intelligenz, um Seiten wahrzunehmen, zu ermitteln, nachzuschlagen, zu destillieren, zu ingestieren und zu überwachen. Jeder Aufruf nimmt zuerst einen context.Context entgegen, Abbruch und Fristen bleiben also in deiner Hand.
github.com/conversionapi/go-sdk · Paket: enconvert · Quelle: conversionapi/go-sdk · Go: 1.21+ · Abhängigkeiten: keine
Installation#
go get github.com/conversionapi/go-sdk
Der Modulpfad endet auf go-sdk, das Paket heißt jedoch enconvert, importiere es also unter einem expliziten Namen: import enconvert "github.com/conversionapi/go-sdk".
Schnellstart#
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 liefert nur dann einen Fehler, wenn der API-Schlüssel leer ist; die funktionalen Optionen beschreibt der Abschnitt Konfiguration. Eine Seite so zu lesen, wie ein Agent es tun sollte, mit angehängtem Qualitätswert, ist ein einziger Aufruf im V2-Namensraum:
op, err := client.V2.Perceive(ctx, "https://example.com", enconvert.PerceiveOptions{
Outputs: []enconvert.PerceiveOutputName{enconvert.PerceiveOutputMarkdown},
})
fmt.Println(op.Outputs["markdown"].URL, *op.RenderQuality) // z. B. 0.93
Jedes Beispiel unten geht von einem client und einem ctx aus, die genau so gebaut wurden.
Was der Client bereitstellt#
Zwölf Methoden hängen an *enconvert.Client und bilden REST-Endpunkte 1:1 ab. Optionen werden immer als Struct-Wert übergeben, nie als Pointer, der Nullwert (enconvert.URLToPDFOptions{}) bedeutet also "alle Standardwerte". Optionale Zahlen und Wahrheitswerte sind durchgehend Pointer-Felder: Nimm dafür die Helfer enconvert.Int, enconvert.Bool, enconvert.Float64 und enconvert.String statt einer Wegwerf-Variable.
| Methode | Endpunkt | Rückgabe |
|---|---|---|
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} (per Polling) |
BatchStatus |
client.V2 hält dreiundzwanzig weitere Methoden in sechs Fähigkeitsgruppen bereit:
| Gruppe | Methoden | Basispfad |
|---|---|---|
| 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 |
Dateikonvertierung#
Uploads akzeptieren jede FileSource: enconvert.FilePath("report.docx") für einen Pfad auf der Festplatte (der Basisname bestimmt Eingabeformat und MIME-Typ), enconvert.FileBytes(buf) für rohe Bytes ohne Namen (hochgeladen als upload.bin, application/octet-stream) oder enconvert.FileInput{Data: buf, Filename: "report.docx"} für rohe Bytes mit explizitem Dateinamen und optionalem ContentType.
ConvertURLToPDF#
Rendert jede erreichbare URL als PDF.
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",
})
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
SaveTo |
string |
-- | Lokaler Pfad, auf den das PDF gestreamt wird. Übergeordnete Verzeichnisse werden für dich angelegt. |
SinglePage |
*bool |
true |
true rendert eine durchgehende Seite. false paginiert anhand von PDFOptions.PageSize. |
PDFOptions |
*PDFOptions |
-- | Seitengröße, Ausrichtung, Ränder, Skalierung, Graustufen, Kopfzeile, Fußzeile. Siehe PDF-Optionen. |
ViewportWidth, ViewportHeight |
*int |
1920, 1080 |
Größe des Browser-Viewports in Pixeln. |
LoadMedia |
*bool |
true |
Wartet vor der Aufnahme auf Bilder und Videos. |
EnableScroll |
*bool |
true |
Scrollt von oben nach unten, um Lazy Loader auszulösen. |
OutputFilename |
string |
auto | Überschreibt den generierten Dateinamen. |
Auth |
*HTTPBasicAuth |
-- | HTTP-Basic-Anmeldedaten für Seiten hinter einem Login. |
Cookies, Headers |
[]BrowserCookie, map[string]string |
-- | Cookies, die vor dem Rendern gesetzt werden (max. 50), und zusätzliche Request-Header (max. 20, Hop-by-Hop wird abgelehnt). |
Alles ab ViewportWidth abwärts lebt im eingebetteten Struct URLRenderOptions, das sich alle URL-basierten Methoden teilen.
Auth nicht mit einem Authorization-Header. Die API lehnt den Konflikt ab, statt zu raten, was du gemeint hast.
ConvertURLToScreenshot und ConvertURLToMarkdown#
Nimm ein PNG einer beliebigen URL auf oder extrahiere sauberes GitHub-Flavored Markdown mit YAML-Frontmatter (title, description, url, links, images). Der Markdown-Konverter entfernt Navigation, Fußzeilen, Werbung und Skripte und behält den Hauptartikeltext.
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"})
Beide nehmen dieselben URLRenderOptions wie ConvertURLToPDF entgegen, plus SaveTo. Keine der beiden akzeptiert SinglePage oder PDFOptions.
ConvertImage#
Konvertiert zwischen jpeg, png, svg, heic und webp in jede Richtung oder rastert ein PDF nach JPEG.
// Aus einem Pfad
result, err := client.ConvertImage(ctx, enconvert.FilePath("photo.heic"),
enconvert.ConvertImageOptions{OutputFormat: "webp", SaveTo: "photo.webp"})
// Aus Bytes, die schon im Speicher liegen
buf, _ := os.ReadFile("photo.heic")
result, err = client.ConvertImage(ctx, enconvert.FileInput{Data: buf, Filename: "photo.heic"},
enconvert.ConvertImageOptions{OutputFormat: "webp", SaveTo: "photo.webp"})
| Option | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
OutputFormat |
string |
Ja | jpeg, png, svg, heic oder webp. jpg wird als Alias für jpeg akzeptiert. |
SaveTo |
string |
-- | Lokaler Pfad, auf den das Ergebnis gestreamt wird. |
OutputFilename |
string |
-- | Überschreibt den generierten Dateinamen. |
Das Eingabeformat ergibt sich aus der Dateiendung (.jpg, .jpeg, .png, .svg, .heic, .webp, .pdf). Nicht unterstützte Paare scheitern lokal, vor jedem Netzwerkaufruf, mit einem Fehler, der die verfügbaren Optionen auflistet:
enconvert.ValidOutputsFor("pdf") // []string{"jpeg"}
enconvert.ValidOutputsFor("json") // []string{"csv", "toml", "xml", "yaml"}
ConvertDocument#
Konvertiert Dokumente und Datenformate. OutputFormat steht standardmäßig auf pdf, wenn es leer bleibt.
// docx zu pdf
_, err := client.ConvertDocument(ctx, enconvert.FilePath("report.docx"),
enconvert.ConvertDocumentOptions{SaveTo: "report.pdf"})
// json zu yaml
_, err = client.ConvertDocument(ctx, enconvert.FilePath("data.json"),
enconvert.ConvertDocumentOptions{OutputFormat: "yaml", SaveTo: "data.yaml"})
Unterstützte Eingaben: .doc, .docx, .xls, .xlsx, .ppt, .pptx, .html, .htm, .odt, .ods, .odp, .ots, .pages, .numbers, .md, .markdown, .csv, .json, .xml, .yaml, .yml, .toml.
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
OutputFormat |
string |
"pdf" |
Zielformat. yml, htm, md und jpg werden auf ihre kanonischen Namen normalisiert. |
SaveTo |
string |
-- | Lokaler Pfad, auf den das Ergebnis gestreamt wird. |
OutputFilename |
string |
-- | Überschreibt den generierten Dateinamen. |
PDFOptions |
*PDFOptions |
-- | Seitenlayout. Nur sinnvoll, wenn die Ausgabe ein PDF ist. |
Die 43 implementierten Paare, verfügbar als Map enconvert.ImplementedConversions, sind: json nach csv, toml, xml, yaml; xml nach csv, json; yaml nach json; csv nach json, xml; toml nach json; markdown nach html, pdf; html nach pdf; doc, excel, ppt, odt, ods, odp, ots, pages und numbers nach pdf; alle 20 geordneten Paare unter jpeg, png, svg, heic, webp; sowie pdf nach jpeg.
Für EPUB gibt es kein eigenes Dokumentpaar. Schicke .epub-Dateien stattdessen durch ConvertToPDF oder ConvertToMarkdown.
ConvertToMarkdown#
Erkennt die Eingabe serverseitig automatisch und liefert sauberes Markdown zurück. Das ist der RAG-Ingestion-Baustein: PDF, DOCX, PPTX, XLSX, CSV, HTML, EPUB, TXT und MD sowie alte und ODF-Office-Formate.
_, err := client.ConvertToMarkdown(ctx, enconvert.FilePath("handbook.pdf"),
enconvert.ConvertToMarkdownOptions{SaveTo: "handbook.md"})
ConvertToMarkdownOptions hat zwei Felder, SaveTo und OutputFilename. Bilder unterstützt dieser Endpunkt nicht, und PDF-Optionen gibt es hier ebenfalls keine. Die Ausgabe behält die Überschriftenhierarchie des Dokuments, sodass ein semantischer Chunker an Überschriften trennen kann statt an willkürlichen Zeichenzahlen.
ConvertToPDF#
Erkennt die Eingabe serverseitig automatisch und liefert ein PDF zurück: Office, ODF, Pages, Numbers, RTF, CSV, HTML, Markdown, Klartext, Rasterbilder, SVG, EPUB oder ein bestehendes PDF, das zur Normalisierung durchgereicht wird.
_, err := client.ConvertToPDF(ctx, enconvert.FilePath("slides.pptx"),
enconvert.ConvertToPDFOptions{SaveTo: "slides.pdf"})
// PDF durchgereicht und in Graustufen umgewandelt
_, err = client.ConvertToPDF(ctx, enconvert.FilePath("scan.pdf"), enconvert.ConvertToPDFOptions{
PDFOptions: &enconvert.PDFOptions{Grayscale: enconvert.Bool(true)},
SaveTo: "scan-gray.pdf",
})
PDFOptions.Grayscale wird hier berücksichtigt. Jedes andere Geometriefeld wird bei anything-to-pdf ignoriert. Nimm ConvertDocument oder ConvertURLToPDF, wenn du Seitengröße, Ausrichtung, Ränder, Skalierung, Kopf- oder Fußzeilen brauchst.
ConvertToPDFOptions hat drei Felder: SaveTo, OutputFilename und PDFOptions.
ConvertWebsiteToPDF und ConvertWebsiteToScreenshot#
Ermittelt jede Seite einer Website, konvertiert jede im Hintergrund und sammelt alles in einem einzigen ZIP. Beide sind ausschließlich asynchron: Sie liefern eine BatchSubmission zurück, und du fragst mit GetBatchStatus ab oder blockierst mit WaitForBatch. Erforderlich ist ein privater API-Schlüssel mit Crawl-Zugriff.
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")
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
CrawlMode |
CrawlMode |
auto |
CrawlModeAuto, CrawlModeSitemap (nur sitemap.xml) oder CrawlModeFull (Sitemap plus BFS-Crawl). |
IncludePatterns |
[]string |
-- | Crawlt nur URLs, die zu diesen Mustern passen, im Full-Crawl-Modus. |
ExcludePatterns |
[]string |
-- | Überspringt URLs, die zu diesen Mustern passen, im Full-Crawl-Modus. |
NotificationEmail |
string |
Projektinhaber | Adresse, die benachrichtigt wird, sobald der Batch fertig ist. |
CallbackURL |
string |
-- | Webhook, der per POST aufgerufen wird, sobald der Batch fertig ist. |
SinglePage |
*bool |
Server-Standard | Nur PDF. Durchgehende Seite oder paginiert. |
PDFOptions |
*PDFOptions |
-- | Nur PDF. Wird auf jede Seite angewandt. |
Alles aus URLRenderOptions wird hier ebenfalls akzeptiert und nur dann pro Seite gesendet, wenn du es setzt. WaitForBatchOptions nimmt Interval (Standard 5 Sekunden), Timeout (Standard 30 Minuten) und SaveTo entgegen. Ein überschrittenes Timeout liefert einen *APIError mit Status 504; ein fertiger Batch ohne ZIP liefert einen mit Status 500. ConvertWebsiteToScreenshot ist identisch, nur ohne SinglePage und PDFOptions, und erzeugt ein ZIP mit PNGs.
Web-Intelligenz (V2)#
Jeder V2-Lesevorgang trägt einen RenderQuality-Wert zwischen 0.0 und 1.0, bereitgestellt als *float64 auf PerceiveResult, DistillItem, WatcherSnapshot und dem Ergebnis des direkten Downloads. Ein niedriger Wert bedeutet, dass die Seite nicht sauber gerendert hat: eine Challenge-Seite, eine Cookie-Wand, eine leere SPA-Hülle, ein HTTP-Fehler. Der Inhalt kommt trotzdem zurück, markiert, zusammen mit einer Deductions-Map, die jeden ausgelösten Abzug benennt, und einem Warnings-Slice. So gelangt ein schlechter Lesevorgang nie unbemerkt in den Kontext deines Agenten. Alle V2-Methoden verlangen einen privaten API-Schlüssel; öffentliche Schlüssel werden abgelehnt. Prüfe den Wert, bevor du irgendetwas glaubst:
if op.RenderQuality != nil && *op.RenderQuality < 0.6 {
log.Printf("low quality read of %s: %v", op.URL, op.Deductions)
}
Perceive#
Rendert eine URL in die Artefakte, die du anforderst. Synchron, mit Artefakt-URLs, die 15 Minuten lang signiert sind.
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)
// Die Artefakt-URLs später neu signieren
again, err := client.V2.GetPerceiveOperation(ctx, op.OperationID)
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
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 |
-- | JSON-Schema für die strukturierte Extraktion über die LLM-Stufe. |
WaitFor, WaitTimeoutMs |
string, *int |
30000 ms |
Ein CSS-Selektor, optional mit css: vorangestellt, oder js:<expr>, samt Zeitbudget (0 bis 60000). |
JSCode |
string |
-- | JavaScript, das nach der Navigation ausgeführt wird, maximal 20000 Zeichen. |
Viewport |
*PerceiveViewport |
1920 x 1080 | Width 320 bis 3840, Height 240 bis 2160. |
Headers, Cookies, Auth |
map[string]string, []BrowserCookie, *HTTPBasicAuth |
-- | Request-Header, gesetzte Cookies, HTTP-Basic-Anmeldedaten. |
CacheMode |
PerceiveCacheMode |
enabled |
enabled (Cache für 1 Stunde), bypass, refresh. |
PDFOptions |
*PDFOptions |
-- | Nur sinnvoll, wenn Outputs den Wert pdf enthält. |
BlockResources |
[]PerceiveResourceType |
-- | image, media, font, stylesheet, script, xhr, fetch, websocket, manifest, other. |
RespectRobots, Mobile |
*bool |
Server-Standard | robots.txt beachten; ein Mobilgerät emulieren. |
OnlyMainContent |
*bool |
true |
Entfernt Navigation, Header, Footer und Cookie-Banner aus dem Markdown-Artefakt und dem main_content-Extrakt. Setze false für die vollständige Seite. |
DirectDownload |
*bool |
false |
Streamt rohe Bytes statt eines JSON-Umschlags. Nimm besser PerceiveDirect. |
ProxyURL, Geolocation und ActionChain werden vom Go-Struct akzeptiert und serialisiert, der Server antwortet auf alle drei aber derzeit mit 422. Lass sie ungesetzt.
Ein einzelnes Artefakt direkt auf die Festplatte zu streamen spart den JSON-Umschlag. PerceiveDirect prüft lokal, dass du genau eine artefakterzeugende Ausgabe angefordert hast:
direct, err := client.V2.PerceiveDirect(ctx, "https://example.com", enconvert.PerceiveOptions{
Outputs: []enconvert.PerceiveOutputName{enconvert.PerceiveOutputPDF},
})
os.WriteFile(direct.Filename, direct.Content, 0o644)
// Ein gespeichertes Artefakt später erneut laden. Übergib "", wenn die Operation nur eines erzeugt hat.
saved, err := client.V2.DownloadPerceiveArtifact(ctx, direct.OperationID, enconvert.PerceiveOutputPDF)
PerceiveDirectResult trägt Content, ContentType, Filename, OperationID, ObjectKey, CacheHit, RenderQuality, SourceStatusCode, ContentHash und WarningsCount, alle aus den Antwort-Headern gelesen. Ein 410-*APIError von DownloadPerceiveArtifact bedeutet, dass das Artefakt aus seiner Aufbewahrungsfrist gefallen ist.
Batches nehmen bis zu 1000 URLs mit einem gemeinsamen Optionsblock entgegen. Kleine Batches werden inline fertig; größere kommen als queued zurück, frage also GetPerceiveBatch ab, bis Status den Wert PerceiveBatchStatusCompleted hat, und lies dann Zip oder 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 ist PerceiveBatchOutputManifest (Standard) oder PerceiveBatchOutputZip. DirectDownload wird bei Batches mit 422 abgelehnt.
Discover#
Zählt die URLs einer Website aus ihrer Sitemap, einem HTTP-Crawl oder beidem auf. Es wird kein Browser gestartet, das macht es schnell und günstig.
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)
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
Mode |
DiscoverMode |
hybrid |
DiscoverModeSitemap, DiscoverModeCrawl oder DiscoverModeHybrid (Sitemap plus HTTP-Crawl). |
MaxURLs, MaxDepth |
*int |
100, 2 |
1 bis 1000 URLs, Crawl-Tiefe 1 bis 5. |
IncludePatterns, ExcludePatterns |
[]string |
-- | Regex-Positivliste, dann Negativliste, re.search-Semantik, je maximal 50. |
SameDomainOnly |
*bool |
true |
Bleibt auf der Domain der Start-URL. |
RespectRobots |
*bool |
Server-Standard | Beachtet robots.txt. |
DiscoverResult liefert dir URL, Mode, Total, URLs, PagesCrawled, Truncated, RobotsRespected, Sources (rohe Zählungen pro Quelle vor der Deduplizierung) und Warnings.
Lookup#
Kategorisierte Websuche, die auf Wunsch die besten Treffer im selben Roundtrip rendert.
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)
}
}
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
Category |
LookupCategory |
web |
web, news, images, scholar, patents, maps. |
Country, Locale |
string |
-- | Google-gl-Ländercode (us, in) und hl-Oberflächensprache (en). |
TimeFilter |
LookupTimeFilter |
-- | hour, day, week, month, year. |
NumResults, Page |
*int |
10, 1 |
1 bis 100 Treffer, Seite 1 bis 10. |
Location |
string |
-- | Freitext-Ort, zum Beispiel Austin, Texas. |
Autocorrect |
*bool |
true |
Lässt den Anbieter Tippfehler in der Suchanfrage korrigieren. |
PerceiveTop |
*int |
0 |
0 bis 10. Führt ein vollständiges Browser-Rendering der Top-N-Ergebnis-URLs aus und hängt jedes PerceiveResult inline an. |
LookupResult trägt außerdem AnswerBox, KnowledgeGraph, PerceiveOperationIDs und Warnings.
Distill#
Schemagesteuerte strukturierte Extraktion. Gib genau eines von URLs (maximal 50) oder DiscoverFrom an; Schema ist immer erforderlich. Beide Regeln werden lokal geprüft, bevor eine Anfrage rausgeht.
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)
Das optionale CSSSchema läuft zuerst und beantwortet mit einfachen Selektoren alles, was es kann; nur die Felder, die es verfehlt, eskalieren auf die LLM-Stufe, und ExtractionTier meldet, welche Stufen tatsächlich geantwortet haben (css, llm, mixed oder none). CSSField.Type ist einer der Werte text, attribute, html, regex, nested, list oder nested_list, verschachtelt bis zu 5 Ebenen tief.
Tausche URLs gegen DiscoverFrom, um in einem Aufruf zu ermitteln und dann zu destillieren. DistillDiscoverFrom nimmt URL, Mode (Standard hybrid) und MaxPages (1 bis 50, Standard 10, begrenzt sowohl Ermittlung als auch Destillation) entgegen:
_, 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#
Verwandelt eine Website, eine URL-Liste oder einen Stapel hochgeladener Dokumente in gechunktes, RAG-fertiges JSONL. Immer asynchron.
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)
}
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
Mode |
IngestMode |
urls |
IngestModeURLs, IngestModeSitemap, IngestModeCrawl, IngestModeFiles. |
URL |
string |
-- | Start-URL. Erforderlich für sitemap und crawl, verboten für urls. |
URLs |
[]string |
-- | Explizite URLs, maximal 1000. Erforderlich für urls, sonst verboten. |
MaxPages, MaxDepth |
*int |
50, 2 |
Ermittlungs-Limit 1 bis 1000 für sitemap und crawl, Tiefe 1 bis 5. |
SameDomainOnly |
*bool |
true |
Bleibt auf der Domain der Start-URL. |
IncludePatterns, ExcludePatterns |
[]string |
-- | Regex-Positivliste, dann Negativliste. |
RespectRobots |
*bool |
Server-Standard | Beachtet robots.txt. |
WaitFor, WaitTimeoutMs |
string, *int |
30000 ms |
Selektor oder js:-Ausdruck, auf den pro Seite gewartet wird, samt Zeitbudget (0 bis 60000). |
Chunk |
*IngestChunkOptions |
-- | MaxWords 32 bis 4000, Standard 512. SentenceOverlap 0 bis 10, Standard 1. |
WebhookURL |
string |
-- | Webhook bei Fertigstellung, HMAC-signiert. |
Die obigen Regeln zu Modus und URL werden clientseitig durchgesetzt: Ingest liefert einen einfachen Go-Fehler statt eines API-Roundtrips, wenn du URLs zusammen mit Mode: IngestModeSitemap sendest.
Hochgeladene Dateien durchlaufen dieselbe Pipeline und denselben Job-Lebenszyklus:
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)}})
Akzeptiert werden PDF, DOCX, PPTX, XLSX, CSV, HTML, EPUB, TXT und MD sowie alte oder ODF-Office-Dateien; mindestens eine Datei ist erforderlich. Job-Verwaltung und Webhook-Verkabelung:
list, err := client.V2.ListIngestJobs(ctx, enconvert.V2ListOptions{Limit: enconvert.Int(20)})
canceled, err := client.V2.CancelIngestJob(ctx, job.JobID) // idempotent
secret, err := client.V2.GetWebhookSecret(ctx) // Secret, SignatureHeader, SignatureScheme, ...
rotated, err := client.V2.RotateWebhookSecret(ctx) // alte Signaturen gelten sofort nicht mehr
retry, err := client.V2.RetryIngestWebhook(ctx, job.JobID)
RetryIngestWebhook antwortet mit 409, wenn der Job nicht abgeschlossen ist, und mit 400, wenn kein Webhook konfiguriert ist. V2ListOptions nimmt Skip und Limit entgegen (1 bis 100, Standard 20).
Watch#
Rendert eine Seite in festem Takt neu und benachrichtigt dich, wenn sie sich ändert.
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)
}
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
FrequencyMinutes |
*int |
60 |
60 bis 43200. Die Stundengrenze ist hart. |
DiffMode |
WatchDiffMode |
auto |
WatchDiffAuto, WatchDiffText, WatchDiffStructured, WatchDiffTables, WatchDiffMetadata. |
TrackFields |
map[string]any |
-- | Feld- oder Selektor-Auswahl, die an die Diff-Engine übergeben wird. |
WebhookURL, NotifyEmail |
string, *bool |
--, true |
HMAC-signierter Änderungs-Webhook und die Frage, ob der Projektinhaber eine E-Mail bekommt. |
// Ein Pointer auf den leeren String löscht den Webhook; nil lässt ihn unangetastet.
_, err = client.V2.UpdateWatcher(ctx, watcher.WatcherID, enconvert.WatcherUpdate{
Status: enconvert.WatcherStatusPaused, WebhookURL: enconvert.String(""),
})
_, err = client.V2.DeleteWatcher(ctx, watcher.WatcherID) // Soft Delete, idempotent
UpdateWatcher verlangt mindestens ein Feld und liefert einen einfachen Go-Fehler, wenn du ihm ein leeres Struct übergibst. Status akzeptiert nur WatcherStatusActive oder WatcherStatusPaused; gelöscht wird über DeleteWatcher, das den stillgelegten Watcher mit Status deleted zurückgibt. ListWatchers und GetWatcher runden die Gruppe ab.
WatcherSnapshot.Changes ist ein Slice roher Maps, die von der überwachten Seite stammen. Escape die Werte, bevor du sie irgendwo renderst.
PDF-Optionen#
PDFOptions teilen sich ConvertURLToPDF, ConvertDocument, ConvertWebsiteToPDF, PerceiveOptions und (nur für Grayscale) ConvertToPDF. Gesendet werden ausschließlich die Felder, die du setzt.
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)},
}
| Feld | Typ | Beschreibung |
|---|---|---|
PageSize |
string |
"A4", "A3", "Letter", "Legal" und Verwandte. |
PageWidth, PageHeight |
*float64 |
Gemeinsam gesetzt überschreiben sie PageSize. |
Orientation |
string |
"portrait" oder "landscape". Standard ist Hochformat. |
Margins |
*PDFMargins |
Top, Bottom, Left, Right, jeweils ein *float64 in Punkt. Alle vier optional. |
Scale |
*float64 |
Render-Skalierung, zum Beispiel 0.9 für 90 %. |
Grayscale |
*bool |
Wandelt das PDF per Nachbearbeitung in Graustufen um. |
Header, Footer |
*PDFHeaderFooter |
Beide haben Content (maximal 2000 Zeichen) und Height. |
Fehlerbehandlung#
Go kennt keine Exception-Klassen, jeder API-Fehlschlag ist daher ein konkreter Typ, *enconvert.APIError, plus drei Prädikate. Error() wird als "[<status>] <message>" dargestellt.
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) // Netzwerkfehler, Context-Abbruch, lokale Validierung
}
}
| Prüfung | Ausgelöst bei | Statuscode |
|---|---|---|
IsAuthenticationError(err) |
Ungültiger, fehlender oder widerrufener Schlüssel | 401, 403 (beide werden als 401 verbucht) |
IsQuotaError(err) |
Jede Antwort, die die API mit 402 beantwortet |
402 |
IsRateLimitError(err) |
Rate-Limit überschritten | 429 |
errors.As(err, &apiErr) |
Jeder andere 4xx- oder 5xx-Fehler | der tatsächliche Code |
Fehler, die das Netzwerk nie erreichen, etwa ein nicht unterstütztes Konvertierungspaar, ein Distill-Aufruf mit URLs und DiscoverFrom gleichzeitig oder ein PerceiveDirect-Aufruf, der zwei Artefakte anfordert, kommen als einfache error-Werte aus errors.New oder fmt.Errorf zurück, nicht als *APIError. Die Antwortcodes sind in der Fehlercode-Referenz katalogisiert.
Timeout-Recovery#
Lange URL-Renderings und große Dokumentkonvertierungen können die Obergrenze eines Reverse Proxy von 60 bis 120 Sekunden überdauern, selbst wenn der Job auf dem Server sauber durchläuft. Das SDK pollt sich da heraus, ganz ohne Code von dir:
- Vor jeder Einzeldatei- und Einzel-URL-Konvertierung erzeugt der Client eine UUIDv4 und sendet sie als
job_id. - Kommt diese Anfrage mit
>= 500zurück, wechselt der Client still aufGET /v1/convert/status/{job_id}und fragt alle 3 Sekunden ab. - Bei
successliefert er das Ergebnis. Beifailedliefert er*APIErrormit Status500und der Meldung des Servers. - Die Polling-Frist beträgt 5 Minuten, danach bekommst du einen
*APIErrormit Status504und der MeldungConversion timed out.
ConversionResult.JobID ist immer gefüllt, auch wenn der synchrone Pfad geklappt hat und die Antwort das Feld weggelassen hat, sodass du sie selbst an GetJobStatus übergeben kannst:
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 und ConvertWebsiteToScreenshot haben keine eigene Job-Zeile zum Abfragen, ein 5xx kommt dort also sofort an die Oberfläche, statt wiederholt zu werden. V2-Methoden nutzen den Job-Fallback ebenfalls nicht. Das Polling läuft innerhalb des context.Context, den du übergibst, ein Abbruch des Contexts beendet das Warten also sofort.
Konfiguration#
client, err := enconvert.New(os.Getenv("ENCONVERT_API_KEY"),
enconvert.WithTimeout(300*time.Second),
enconvert.WithBaseURL("https://api.enconvert.com"),
)
| Konstruktor-Eingabe | Typ | Standard | Beschreibung |
|---|---|---|---|
apiKey (erstes Argument) |
string |
erforderlich | Privater API-Schlüssel. New liefert einen Fehler, wenn er leer ist. |
WithTimeout(d) |
time.Duration |
300 * time.Second |
Setzt Timeout am internen *http.Client, was auch Downloads einschließt. |
WithBaseURL(u) |
string |
https://api.enconvert.com |
Überschreibung für ein selbst gehostetes Gateway. Schrägstriche am Ende werden entfernt. |
Fristen pro Aufruf legen sich über den Context auf das Client-Timeout: Verpacke ihn mit context.WithTimeout(context.Background(), 30*time.Second) und übergib ihn als erstes Argument.
Der Client lässt sich gefahrlos über Goroutinen hinweg teilen: Er hält einen *http.Client und keinen veränderlichen Zustand pro Anfrage. Baue einen beim Start und verwende ihn wieder. Schlüsseltypen und Rotation beschreibt die Authentifizierung.
Form des Ergebnisses#
Einzeldatei- und Einzel-URL-Konvertierungen liefern ein ConversionResult:
type ConversionResult struct {
PresignedURL string // signierte Download-URL für die Ausgabe
ObjectKey string // Objektschlüssel im Speicher
Filename string // serverseitiger Dateiname
FileSize *int64 // Bytes, nil wenn die API das Feld weglässt
ConversionTimeSeconds *float64 // nil wenn die API das Feld weglässt
JobID string // wird immer vom Client gesetzt
}
Vorsignierte URLs sind kurzlebig. Übergib SaveTo, damit das SDK die Bytes für dich auf die Festplatte streamt, oder rufe die URL selbst ab und lege die Datei in deinem eigenen Bucket ab, wenn du langfristigen Zugriff brauchst. Der Download trägt bewusst deinen API-Schlüssel nicht mit, denn eine vorsignierte URL authentifiziert sich selbst, und den Schlüssel an einen Storage-Host weiterzureichen würde ihn preisgeben.
V2-Artefakte kommen als V2OutputArtifact-Werte an, geschlüsselt nach Ausgabename, und tragen jeweils URL (15 Minuten lang vorsigniert und bei jedem Status-GET neu signiert), ObjectKey, SizeBytes, ContentType und ExpiresIn (standardmäßig 900 Sekunden). PerceiveResult umhüllt sie mit den Ehrlichkeits-Metadaten: RenderQuality, StatusCode, Deductions, CacheHit, Warnings, ContentHash, URLFinal, Structured, ExtractionTier, Tokens, CostCents, DurationMs und OptionsEcho, das die vom Server tatsächlich berücksichtigten Optionen zurückspiegelt, wobei Geheimnisse auf Wahrheitswerte reduziert werden.
Quellcode und Issues#
- Modul und Quelle: github.com/conversionapi/go-sdk
- Version: zur Laufzeit als Konstante
enconvert.Versionverfügbar - Lizenz: MIT, keine Fremdabhängigkeiten
Weiterführend: alle SDKs, V2-Übersicht, perceive, discover, lookup, distill, ingest, watch, Endpunkt-Übersicht, Parameter und Optionen sowie dein Dashboard für die Schlüssel.
Häufig gestellte Fragen#
Wie konvertiere ich Dateien in Go?#
Führe go get github.com/conversionapi/go-sdk aus, baue einen Client mit enconvert.New(os.Getenv("ENCONVERT_API_KEY")) und rufe dann eine typisierte Methode wie ConvertDocument, ConvertImage oder ConvertURLToPDF auf. Übergib SaveTo im Options-Struct, dann streamt das SDK die fertige Datei direkt an diesen Pfad und legt übergeordnete Verzeichnisse bei Bedarf an.
Wie konvertiere ich in Go eine URL nach PDF?#
Rufe client.ConvertURLToPDF(ctx, url, enconvert.URLToPDFOptions{SaveTo: "page.pdf"}) auf. Setze SinglePage: enconvert.Bool(false), um zu paginieren statt eine durchgehende Seite zu erzeugen, und übergib PDFOptions für Seitengröße, Ausrichtung, Ränder, Skalierung, Graustufen, Kopf- und Fußzeilen.
Wie konvertiere ich in Go DOCX nach PDF?#
client.ConvertDocument(ctx, enconvert.FilePath("report.docx"), enconvert.ConvertDocumentOptions{SaveTo: "report.pdf"}). Das Ausgabeformat steht standardmäßig auf pdf, du kannst OutputFormat also leer lassen. Dieselbe Methode bewältigt Eingaben in XLSX, PPTX, ODT, ODS, ODP, OTS, Pages, Numbers, HTML, Markdown, CSV, JSON, XML, YAML und TOML.
Wie konvertiere ich in Go HEIC nach WebP?#
client.ConvertImage(ctx, enconvert.FilePath("photo.heic"), enconvert.ConvertImageOptions{OutputFormat: "webp", SaveTo: "photo.webp"}). Das Eingabeformat wird aus der Dateiendung gelesen, und alle 20 geordneten Paare unter jpeg, png, svg, heic und webp funktionieren genauso. Nicht unterstützte Paare scheitern lokal, bevor eine Anfrage gesendet wird.
Zieht das Go-SDK Fremdabhängigkeiten nach sich?#
Nein. go.mod deklariert das Modul und eine Untergrenze von Go 1.21, sonst nichts. Der Client baut auf net/http, encoding/json, mime/multipart und crypto/rand aus der Standardbibliothek auf, er fügt deinem Build also keine transitive Lieferkette hinzu.
Wie lese ich eine Webseite in Go als sauberes Markdown aus?#
Es gibt zwei Wege. client.ConvertURLToMarkdown liefert GitHub-Flavored Markdown mit YAML-Frontmatter und ist der einfachste Pfad. client.V2.Perceive mit Outputs: []enconvert.PerceiveOutputName{enconvert.PerceiveOutputMarkdown} gibt dir dasselbe Markdown plus einen RenderQuality-Wert, Deductions, Warnings und die Möglichkeit, im selben Rendering Screenshots, Links oder eine strukturierte Extraktion zu ergänzen.
Was bedeutet Render-Qualität und warum sollte ich sie prüfen?#
RenderQuality ist ein *float64 zwischen 0.0 und 1.0, das an jedem V2-Lesevorgang hängt. Der Wert sinkt, wenn die Seite nicht ehrlich gerendert hat: eine Bot-Challenge, eine Login-Schranke, ein Cookie-Banner über einer leeren Hülle oder ein HTTP-Fehlerstatus. Der Inhalt wird trotzdem zurückgegeben statt verschluckt, prüfe also den Wert (und die Deductions-Map, die jeden Abzug benennt), bevor du den Text an ein Modell gibst.
Wie setze ich in Go ein Timeout pro Anfrage oder breche eine Konvertierung ab?#
Jede Methode nimmt zuerst einen context.Context entgegen. Verpacke ihn mit context.WithTimeout oder context.WithCancel für die Kontrolle pro Aufruf; WithTimeout am Konstruktor setzt das grundlegende HTTP-Client-Timeout für alle Aufrufe, einschließlich des Downloads einer SaveTo-Datei.
Was passiert, wenn eine lange Konvertierung ins Proxy-Timeout läuft?#
Das SDK sendet bei jeder Einzeldatei- und Einzel-URL-Konvertierung eine clientseitig erzeugte job_id mit. Liefert die Anfrage >= 500, fragt es bis zu 5 Minuten lang alle 3 Sekunden GET /v1/convert/status/{job_id} ab und gibt bei success das Ergebnis zurück, bei failed einen *APIError. Wird die Frist überschritten, bekommst du einen *APIError mit Status 504. Website-Batch-Einreichungen überspringen diesen Fallback bewusst.
Kann ich das Go-SDK in einem Desktop- oder Mobil-Client ausliefern?#
Nein. Es authentifiziert sich mit einem privaten API-Schlüssel, und V2-Endpunkte lehnen öffentliche Schlüssel rundweg ab. Halte den Client auf einem Server, den du kontrollierst, und lass deine App mit diesem sprechen. Das Schlüsselmodell beschreibt die Authentifizierung.
Lässt sich der Go-Client aus mehreren Goroutinen nutzen?#
Ja. *enconvert.Client umhüllt einen einzelnen *http.Client und hält keinen veränderlichen Zustand pro Anfrage, baue also einen beim Start und teile ihn überall.