synoppy

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2026 License: MIT Imports: 8 Imported by: 0

README

synoppy-go

Go Reference

Give your AI agents the whole web. Synoppy is the web-data layer for AI agents — one key to read, crawl, map, extract, classify & enrich any site, plus screenshots and image scraping. Standard library only, zero dependencies.

Get a free key → · Docs · synoppy.com

go get github.com/Synoppy/synoppy-go

Quickstart

package main

import (
	"context"
	"fmt"
	"os"

	synoppy "github.com/Synoppy/synoppy-go"
)

func main() {
	client := synoppy.New(os.Getenv("SYNOPPY_API_KEY")) // key looks like syn_...
	ctx := context.Background()

	// Read any URL -> clean markdown (+ render the page first if needed)
	page, err := client.Read(ctx, "https://stripe.com/blog", map[string]any{
		"formats":         []string{"markdown"},
		"onlyMainContent": true,
		"render":          "auto", // true | false | "auto"
		"waitMs":          500,
		"timeoutMs":       15000,
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(page["markdown"])
	fmt.Println(page["metadata"]) // title, description, wordCount, rendered, bytesIn, ...

	// Screenshot a page (PNG data URL)
	shot, _ := client.Screenshot(ctx, "https://stripe.com", map[string]any{"fullPage": true})
	fmt.Println(shot["screenshot"]) // data:image/png;base64,...

	// Crawl a site (limit 1-25)
	site, _ := client.Crawl(ctx, "https://example.com", 25)
	fmt.Println(site["count"], "of", site["discovered"], "pages")

	// Brand intelligence — by url, domain, or work email
	brand, _ := client.Enrich(ctx, "https://linear.app")
	fmt.Println(brand["colors"], brand["fonts"])
}

Methods

Every method takes a context.Context and returns synoppy.Result (a map[string]any), so every field of the JSON response is reachable by key.

Method Endpoint Signature
Read POST /api/scrape Read(ctx, url string, opts map[string]any)
Screenshot POST /api/screenshot Screenshot(ctx, url string, opts map[string]any)
Crawl POST /api/crawl Crawl(ctx, url string, limit int)
Map POST /api/map Map(ctx, url string)
Search POST /api/search Search(ctx, SearchOptions{Query: "…", MaxResults: 5, Markdown: true})
Extract POST /api/extract Extract(ctx, url, prompt string)
ExtractWithSchema POST /api/extract ExtractWithSchema(ctx, url, prompt string, schema json.RawMessage) — constrain output to a JSON Schema (typed output)
Classify POST /api/classify Classify(ctx, url string, labels []string)
Enrich / Brand POST /api/brand Enrich(ctx, url string) / Brand(ctx, in BrandInput)
Images POST /api/images Images(ctx, url string)
Read options (map[string]any)

formats ([]string of "markdown"/"html"/"text"), onlyMainContent (bool), timeoutMs (number), render (bool or "auto"), waitMs (number). Response: metadata (title, description, language, siteName, author, ogImage, sourceUrl, statusCode, wordCount, fetchedAt, rendered, bytesIn), markdown/html/text, renderMs, latencyMs.

Screenshot options (map[string]any)

fullPage (bool), waitMs (number), timeoutMs (number). Response: screenshot (PNG data URL), sourceUrl, statusCode, fullPage, latencyMs. May return 503 RENDER_UNAVAILABLE (surfaced as an *APIError).

Classify

Default mode (labels == nil) returns data with NAICS/SIC fields: industry, naics_code, naics_title, naics_sector, naics_sector_title, naics_valid, sic_code, sic_title, sic_division, sic_division_title, sic_valid, categories, confidence. Passing labels switches to label mode, returning data {label, matched, confidence, reasoning}.

Brand by domain or email
brand, _ := client.Brand(ctx, synoppy.BrandInput{Domain: "linear.app"})
brand, _ = client.Brand(ctx, synoppy.BrandInput{Email: "founder@linear.app"}) // maps to the domain
Coming soon

/api/act is not live yet, so the SDK does not expose it. A method will be added once that endpoint ships.

Credits

Every successful response includes the metered billing fields creditsUsed and creditsRemaining. Read them with the helpers on Result:

res, err := client.Read(ctx, "https://example.com", nil)
if err != nil {
	panic(err)
}
if used, ok := res.CreditsUsed(); ok {
	fmt.Printf("spent %.0f credits\n", used)
}
if left, ok := res.CreditsRemaining(); ok {
	fmt.Printf("%.0f credits remaining\n", left)
} else {
	fmt.Println("credits remaining: unlimited / unmetered")
}

CreditsRemaining reports ok == false when the API returns null (unmetered or unlimited keys). You can also read the raw values directly, e.g. res["creditsUsed"].

Errors

Failed requests return an *synoppy.APIError with Code and Status:

_, err := client.Crawl(ctx, "https://example.com", 0)
var apiErr *synoppy.APIError
if errors.As(err, &apiErr) {
	fmt.Println(apiErr.Code, apiErr.Status)
}

Configuration

client := synoppy.New(
	os.Getenv("SYNOPPY_API_KEY"),
	synoppy.WithBaseURL("https://api.synoppy.com"), // override the base URL
	synoppy.WithHTTPClient(&http.Client{Timeout: 90 * time.Second}),
)

MIT licensed.

Documentation

Overview

Package synoppy is the official Go SDK for the Synoppy web-data API — scrape, screenshot, crawl, map, extract, classify, enrich (brand), images, and search on one key.

Every successful response carries metered billing fields: use Result.CreditsUsed and Result.CreditsRemaining to read them.

Index

Constants

View Source
const Version = "1.1.1"

Version is the SDK version, sent as part of the User-Agent header.

Variables

This section is empty.

Functions

This section is empty.

Types

type APIError

type APIError struct {
	Message string
	Code    string
	Status  int
}

APIError is returned when the API responds with an error.

func (*APIError) Error

func (e *APIError) Error() string

type BrandInput

type BrandInput struct {
	URL    string
	Domain string
	Email  string
}

BrandInput selects how a brand is looked up. Exactly one of URL, Domain, or Email should be set; the API maps a work Email to its Domain. If more than one is set, URL takes precedence, then Domain, then Email.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a Synoppy API client.

func New

func New(apiKey string, opts ...Option) *Client

New creates a Client. apiKey is required and must be a Synoppy key (prefixed "syn_"), sent as "Authorization: Bearer syn_...".

func (*Client) Brand

func (c *Client) Brand(ctx context.Context, in BrandInput) (Result, error)

Brand (POST /api/brand) resolves a URL, domain, or work email into a brand profile. See Enrich for the response shape.

func (*Client) Classify

func (c *Client) Classify(ctx context.Context, url string, labels []string) (Result, error)

Classify (POST /api/classify) returns an industry classification or a best-matching label (requires a key).

With labels == nil the default NAICS/SIC mode runs, returning data{industry, naics_code, naics_title, naics_sector, naics_sector_title, naics_valid, sic_code, sic_title, sic_division, sic_division_title, sic_valid, categories, confidence}. When labels are supplied, the result data is {label, matched, confidence, reasoning}. Both modes carry creditsUsed/creditsRemaining.

func (*Client) Crawl

func (c *Client) Crawl(ctx context.Context, url string, limit int) (Result, error)

Crawl (POST /api/crawl) reads each page of a site (requires a key). limit is clamped by the API to 1-25; a limit <= 0 uses the API default. The result carries domain, discovered, count, pages[{url,title,markdown,words}], credits, latencyMs, and creditsUsed/creditsRemaining.

func (*Client) Enrich

func (c *Client) Enrich(ctx context.Context, url string) (Result, error)

Enrich (POST /api/brand) resolves a URL into a brand profile. It is a convenience wrapper over Brand for the common url case.

The result carries domain, name, description, logo, colors ([]string), fonts ([]string), address, socials ([{label,url}]), bytesIn, latencyMs, and creditsUsed/creditsRemaining.

func (*Client) Extract

func (c *Client) Extract(ctx context.Context, url, prompt string) (Result, error)

Extract (POST /api/extract) returns structured JSON via AI (requires a key). prompt may be empty; it is sent under the "prompt" key (the API also accepts the "instruction" alias). The result carries url, model, data, metadata, truncated, usage{inputTokens,outputTokens}, latencyMs, and creditsUsed/creditsRemaining.

func (*Client) ExtractWithSchema added in v1.1.0

func (c *Client) ExtractWithSchema(ctx context.Context, url, prompt string, schema json.RawMessage) (Result, error)

ExtractWithSchema is Extract with an optional JSON Schema that constrains the output to a caller-defined shape (for example a Zod schema's JSON-Schema output). When schema is nil this behaves exactly like Extract; otherwise the schema is sent under the "schema" key and the returned data conforms to it.

func (*Client) Images

func (c *Client) Images(ctx context.Context, url string) (Result, error)

Images (POST /api/images) returns every image on a page. The result carries url, count, images ([{src,alt,width,height}]), bytesIn, latencyMs, and creditsUsed/creditsRemaining.

func (*Client) Map

func (c *Client) Map(ctx context.Context, url string) (Result, error)

Map (POST /api/map) discovers every URL on a domain. The result carries domain, urls ([]string), count, source ("sitemap"|"links"), latencyMs, and creditsUsed/creditsRemaining.

func (*Client) Read

func (c *Client) Read(ctx context.Context, url string, opts map[string]any) (Result, error)

Read (POST /api/scrape) fetches a URL and returns clean markdown / HTML / text plus page metadata.

opts may include any of: "formats" ([]string of "markdown"|"html"|"text"), "onlyMainContent" (bool), "timeoutMs" (number), "render" (bool or "auto"), "waitMs" (number). The result carries metadata{title, description, language, siteName, author, ogImage, sourceUrl, statusCode, wordCount, fetchedAt, rendered, bytesIn}, markdown/html/text, renderMs, latencyMs, and creditsUsed/creditsRemaining.

func (*Client) Screenshot

func (c *Client) Screenshot(ctx context.Context, url string, opts map[string]any) (Result, error)

Screenshot (POST /api/screenshot) captures a PNG of a page and returns it as a data URL in result["screenshot"].

opts may include any of: "fullPage" (bool), "waitMs" (number), "timeoutMs" (number). The result carries screenshot, sourceUrl, statusCode, fullPage, latencyMs, and creditsUsed/creditsRemaining. The endpoint can return 503 RENDER_UNAVAILABLE, surfaced as an *APIError.

func (*Client) Search added in v1.1.0

func (c *Client) Search(ctx context.Context, opts SearchOptions) (*SearchResponse, error)

Search (POST /api/search) runs a web search for agents and returns clean source URLs (requires a key). With opts.Markdown the clean markdown of each result is read in the same trip. opts.Query is required.

type Option

type Option func(*Client)

Option configures a Client.

func WithBaseURL

func WithBaseURL(u string) Option

WithBaseURL overrides the API base URL (default https://synoppy.com).

func WithHTTPClient

func WithHTTPClient(h *http.Client) Option

WithHTTPClient sets a custom *http.Client.

type Result

type Result map[string]any

Result is a decoded JSON response body. Because the underlying type is map[string]any, every field returned by the API is reachable by key (for example result["metadata"], result["pages"], result["screenshot"]). Helper accessors are provided for the billing fields common to every successful response.

func (Result) CreditsRemaining

func (r Result) CreditsRemaining() (float64, bool)

CreditsRemaining reports the credits left on the key after the call. The API may return null (unmetered/unlimited keys), in which case the second return value is false even though the field was present.

func (Result) CreditsUsed

func (r Result) CreditsUsed() (float64, bool)

CreditsUsed reports how many credits the call consumed. The boolean is false when the field is absent.

type SearchOptions added in v1.1.0

type SearchOptions struct {
	// Query is the search query (required).
	Query string `json:"query"`
	// MaxResults bounds the number of results returned (1-15, default 5).
	MaxResults int `json:"maxResults,omitempty"`
	// Markdown also reads each result to clean markdown, in one trip. Billed
	// as additional reads.
	Markdown bool `json:"markdown,omitempty"`
	// IncludeDomains restricts results to these domains.
	IncludeDomains []string `json:"includeDomains,omitempty"`
	// ExcludeDomains drops results from these domains.
	ExcludeDomains []string `json:"excludeDomains,omitempty"`
	// Fanout expands the query into variations for higher recall (costs more).
	Fanout bool `json:"fanout,omitempty"`
}

SearchOptions configures Search. Query is required; the remaining fields are optional and omitted from the request when left at their zero value.

type SearchResponse added in v1.1.0

type SearchResponse struct {
	Success          bool           `json:"success"`
	Query            string         `json:"query"`
	Results          []SearchResult `json:"results"`
	LatencyMs        int            `json:"latencyMs"`
	CreditsUsed      int            `json:"creditsUsed"`
	CreditsRemaining *int           `json:"creditsRemaining"`
}

SearchResponse is the decoded response from Search. CreditsRemaining is nil for unmetered/unlimited keys (the API returns null).

type SearchResult added in v1.1.0

type SearchResult struct {
	Title    string `json:"title"`
	URL      string `json:"url"`
	Snippet  string `json:"snippet"`
	Markdown string `json:"markdown,omitempty"`
}

SearchResult is a single hit returned by Search. Markdown is populated only when SearchOptions.Markdown was set.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL