chocodata

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 11 Imported by: 0

README

chocodata-go

Official Go SDK for the Chocodata web scraping API.

Methods for the endpoints most people start with, a generic Scrape for the rest of the catalog, context-aware cancellation, retry with backoff, and a typed error. No dependencies beyond the standard library.

go get github.com/ChocoData-com/chocodata-go

Go 1.21+.

Quick start

package main

import (
	"context"
	"fmt"
	"log"

	chocodata "github.com/ChocoData-com/chocodata-go"
)

func main() {
	client := chocodata.New("asa_live_YOUR_KEY")

	product, err := client.AmazonProduct(context.Background(), chocodata.Params{
		"query": "0143127748",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(product["asin"], product["title"])
}

Get a key at chocodata.com. The free tier is 1,000 requests, one time, no card.

Authentication

The key travels as a query parameter, which the SDK handles for you. There is no header auth: sending Authorization: Bearer or X-API-Key returns 401.

Endpoints

Every method below was smoke-tested against production before release.

ctx := context.Background()

// Ecommerce
client.AmazonProduct(ctx, chocodata.Params{"query": "0143127748"})
client.AmazonProduct(ctx, chocodata.Params{"query": "0143127748", "domain": "de"})
client.AmazonSearch(ctx, chocodata.Params{"query": "laptop"})

client.WalmartProduct(ctx, chocodata.Params{"url": "https://www.walmart.com/ip/19075520026"})
client.WalmartSearch(ctx, chocodata.Params{"query": "laptop"})

client.EbayProduct(ctx, chocodata.Params{"url": "https://www.ebay.com/itm/298520538688"})
client.EbaySearch(ctx, chocodata.Params{"query": "laptop"})

// Search engines  (note: Bing takes "q", not "query")
client.BingSearch(ctx, chocodata.Params{"q": "coffee", "count": 10})
client.BingImages(ctx, chocodata.Params{"q": "red panda", "count": 20, "safe_search": "strict"})

// Social / video
client.TiktokProfile(ctx, chocodata.Params{"username": "rotana"})
client.YoutubeVideo(ctx, chocodata.Params{"video_id": "dQw4w9WgXcQ"})
client.InstagramProfile(ctx, chocodata.Params{"username": "nasa"})

Parameters are not uniform across targets, and the SDK does not pretend otherwise. AmazonProduct takes query; WalmartProduct takes url or id and rejects query; BingSearch takes q.

Everything else

The catalog has 499 endpoints. Anything without a dedicated method decodes into whatever you give it:

var out chocodata.Result
err := client.Scrape(ctx, "reddit", "post", chocodata.Params{
	"post_id":   "627akk",
	"subreddit": "askscience",
}, &out)

Scrape unmarshals into any target, so you can decode straight into your own struct:

type Product struct {
	ASIN  string  `json:"asin"`
	Title string  `json:"title"`
	Price float64 `json:"price"`
}
var p Product
err := client.Scrape(ctx, "amazon", "product", chocodata.Params{"query": "0143127748"}, &p)

Errors

_, err := client.TiktokProfile(ctx, chocodata.Params{"username": "a-handle-that-is-gone"})

var apiErr *chocodata.Error
if errors.As(err, &apiErr) {
	fmt.Println(apiErr.Status)    // 404
	fmt.Println(apiErr.Code)      // "item_not_found"
	fmt.Println(apiErr.Retryable) // false
	fmt.Println(apiErr.RequestID) // for support
}
Status Code Meaning
400 invalid_params A required parameter is missing or the wrong type. The body names it.
401 INVALID_API_KEY Key missing, unrecognised, or revoked.
402 INSUFFICIENT_CREDITS Balance exhausted.
404 item_not_found The item genuinely does not exist. Not retryable.
429 RATE_LIMITED Over 120 requests / 60s, or over your plan's concurrency.
502 extraction_failed / target_unreachable Retryable; the SDK already retried.

You are only charged on a 2xx. Errors cost no credits.

Options

client := chocodata.New("asa_live_YOUR_KEY",
	chocodata.WithMaxRetries(3),                                  // default 2
	chocodata.WithHTTPClient(&http.Client{Timeout: 2 * time.Minute}),
	chocodata.WithDebug(true),
)

Retryable failures (429, 5xx, network) are retried with exponential backoff plus jitter. The SDK trusts the server's retryable flag, so a 404 is never retried. Context cancellation is always honoured and never retried.

Concurrency

Requests are 120 per key per 60 seconds, plus a per-plan concurrency ceiling.

var wg sync.WaitGroup
for _, asin := range []string{"0143127748", "B09B8V1LZ3", "B0BSHF7WHW"} {
	wg.Add(1)
	go func(a string) {
		defer wg.Done()
		p, err := client.AmazonProduct(ctx, chocodata.Params{"query": a})
		if err != nil {
			log.Println(a, err)
			return
		}
		fmt.Println(p["asin"], p["title"])
	}(asin)
}
wg.Wait()

License

MIT

Documentation

Overview

Package chocodata is the official Go SDK for the Chocodata web scraping API.

The API is one GET per call:

https://api.chocodata.com/api/v1/{target}/{resource}?api_key=...

The key travels as a QUERY PARAMETER. There is no header auth: sending Authorization: Bearer or X-API-Key returns 401 (verified 2026-07-28).

Parameters are not uniform across targets, so this SDK exposes the endpoints it has verified as methods with their real parameter names, and everything else through Scrape. amazon.product takes "query", walmart.product takes "url" or "id" and rejects "query", and bing.search takes "q".

Index

Constants

View Source
const (
	// Version of this SDK, sent in the User-Agent.
	Version = "0.1.0"
	// DefaultBaseURL is the production API root.
	DefaultBaseURL = "https://api.chocodata.com/api/v1"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	BaseURL    string
	HTTPClient *http.Client
	// MaxRetries applies to retryable failures only. Default 2.
	MaxRetries int
	// Debug logs each call to stderr via the Logf hook.
	Debug bool
	Logf  func(format string, args ...any)
	// contains filtered or unexported fields
}

Client talks to the Chocodata API. The zero value is not usable; call New.

func New

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

New returns a Client. The API key is required; get one at https://chocodata.com.

func (*Client) AmazonProduct

func (c *Client) AmazonProduct(ctx context.Context, p Params) (Result, error)

AmazonProduct fetches one product. Pass "query" (ASIN/ISBN) or "url", optionally "domain" to pick the marketplace (prices localise to it).

func (*Client) AmazonSearch

func (c *Client) AmazonSearch(ctx context.Context, p Params) (Result, error)

AmazonSearch runs a search. Requires "query".

func (*Client) BingImages

func (c *Client) BingImages(ctx context.Context, p Params) (Result, error)

BingImages returns image results. Requires "q". safe_search "strict" (the default) also drops rows Bing flagged explicit and reports filtered_count.

func (*Client) BingSearch

func (c *Client) BingSearch(ctx context.Context, p Params) (Result, error)

BingSearch returns web results. The parameter is "q", not "query".

func (*Client) EbayProduct

func (c *Client) EbayProduct(ctx context.Context, p Params) (Result, error)

EbayProduct fetches one listing by "url" or "id". Returns an ISO currency plus currency_symbol, so listings are comparable across marketplaces.

func (*Client) EbaySearch

func (c *Client) EbaySearch(ctx context.Context, p Params) (Result, error)

EbaySearch runs a search. Requires "query".

func (*Client) InstagramProfile

func (c *Client) InstagramProfile(ctx context.Context, p Params) (Result, error)

InstagramProfile fetches a public profile. Requires "username".

func (*Client) Scrape

func (c *Client) Scrape(ctx context.Context, target, resource string, params Params, out any) error

Scrape calls any endpoint in the catalog and decodes the JSON into out, which is typically *map[string]any or a struct you define. This is the same code path the typed helpers use.

func (*Client) TiktokProfile

func (c *Client) TiktokProfile(ctx context.Context, p Params) (Result, error)

TiktokProfile fetches a public profile by "username" or "url". A handle that no longer resolves returns a 404 item_not_found.

func (*Client) WalmartProduct

func (c *Client) WalmartProduct(ctx context.Context, p Params) (Result, error)

WalmartProduct fetches one item. Pass "url" or "id"; it does not accept "query".

func (*Client) WalmartSearch

func (c *Client) WalmartSearch(ctx context.Context, p Params) (Result, error)

WalmartSearch runs a search. Requires "query".

func (*Client) YoutubeVideo

func (c *Client) YoutubeVideo(ctx context.Context, p Params) (Result, error)

YoutubeVideo fetches one video by "video_id" or "url".

type Error

type Error struct {
	Status    int
	Code      string
	Message   string
	Retryable bool
	RequestID string
}

Error is a structured API failure. Retryable is the server's own judgement, so a 404 is never retried while a 502 is.

func (*Error) Error

func (e *Error) Error() string

type Option

type Option func(*Client)

Option configures a Client.

func WithBaseURL

func WithBaseURL(u string) Option

WithBaseURL overrides the API root. Mostly for testing.

func WithDebug

func WithDebug(on bool) Option

WithDebug logs every request.

func WithHTTPClient

func WithHTTPClient(h *http.Client) Option

WithHTTPClient supplies your own *http.Client, e.g. with a custom transport.

func WithMaxRetries

func WithMaxRetries(n int) Option

WithMaxRetries sets the retry budget for retryable failures.

type Params

type Params map[string]any

Params is a set of query parameters for an endpoint. Values may be string, int, bool, or float64; anything else is rendered with fmt.Sprint.

type Result

type Result map[string]any

Result is the default decode target: the raw JSON object.

Jump to

Keyboard shortcuts

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