Help us shape the future of Go! Take the 2026 Go Developer Survey

cryptopanic

package module
v1.1.1 Latest Latest
Warning

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

Go to latest
Published: Sep 2, 2026 License: MIT Imports: 13 Imported by: 0

README

CryptoPanic Golang SDK

Cryptopanic API Golang

CI Go Version License Codecov GitHub Release GoDoc

A small, typed, context-aware Go client for the CryptoPanic API.

Use it when your application needs to read crypto news, filter posts by currencies or sentiment, consume RSS, or access the authenticated portfolio endpoint without hand-building URLs and decoding JSON in every service.

The SDK deliberately stays close to the public CryptoPanic API. It does not invent a portfolio schema, hide server-side plan rules, or force a framework on your application.

Contents

Why this SDK?

Calling a news API should leave you time to work on your product, not make you maintain another layer of URL construction and response plumbing. cryptopanic-go handles the predictable parts and keeps the rest visible:

  • Typed JSON models — work with Post, PostsPage, and related structs instead of decoding maps yourself.
  • A context-first API — every network method accepts context.Context, so deadlines and cancellation fit naturally into HTTP handlers, workers, and CLI tools.
  • Safe credential handling — the token is sent only where the API expects it and is redacted from pagination URLs and SDK errors.
  • Useful errors — inspect common HTTP failures with errors.Is, and get structured details with errors.As.
  • Careful retries — opt in to retries for rate limits, selected server errors, and transient network failures.
  • No runtime dependencies — the package uses only Go's standard library.
  • Safe concurrent use — a configured Client can be shared between goroutines.

Requirements and installation

  • Go 1.22 or newer.
  • A CryptoPanic auth token for authenticated API calls.
go get github.com/tigusigalpa/cryptopanic-go

Quick start

Set the token in the environment before starting your application:

export CRYPTOPANIC_AUTH_TOKEN="your-token"

Then create one client and reuse it:

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"

    cryptopanic "github.com/tigusigalpa/cryptopanic-go"
)

func main() {
    if os.Getenv("CRYPTOPANIC_AUTH_TOKEN") == "" {
        log.Fatal("CRYPTOPANIC_AUTH_TOKEN is not set")
    }

    client, err := cryptopanic.NewFromEnv(
        cryptopanic.WithPlan(cryptopanic.PlanGrowth),
        cryptopanic.WithTimeout(10*time.Second),
        cryptopanic.WithRetryPolicy(cryptopanic.RetryPolicy{MaxAttempts: 3}),
    )
    if err != nil {
        log.Fatal(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    page, err := client.Posts(ctx, cryptopanic.PostsQuery{
        Currencies: []string{"BTC", "ETH"},
        Filter:     cryptopanic.FilterRising,
        Page:       cryptopanic.IntPtr(1),
    })
    if err != nil {
        log.Fatal(err)
    }

    for _, post := range page.Results {
        fmt.Printf("[%s] %s\n", post.Kind, post.Title)
    }
}

If you already have the token in application configuration, pass it directly instead:

client := cryptopanic.New(
    token,
    cryptopanic.WithPlan(cryptopanic.PlanGrowth),
)

NewFromEnv returns ErrMissingAuthToken when CRYPTOPANIC_AUTH_TOKEN is empty. New accepts the token directly and returns a client immediately.

Configuration

Environment variables

NewFromEnv reads the token from CRYPTOPANIC_AUTH_TOKEN. The package does not read the plan from the environment automatically; choose it explicitly with WithPlan so the URL used by the application is visible in code.

Variable Description Default
CRYPTOPANIC_AUTH_TOKEN CryptoPanic auth token; required by NewFromEnv —

Never commit a token, put it in a URL you log, or print it while debugging. The SDK does not log the token, include it in error messages, or expose it in pagination URLs.

Client options
Option What it controls
WithPlan(plan) The plan segment used in the API path.
WithBaseURL(url) The API base URL, primarily useful with a mock server. The SDK appends /{plan}/v2/.
WithHTTPClient(client) A custom *http.Client for proxies, transports, TLS, or tests.
WithTimeout(duration) The timeout on the underlying http.Client.
WithRetryPolicy(policy) Retry limits and backoff settings. Retries are off by default.
WithUserAgent(value) Replaces the default User-Agent header.
WithSleeper(sleeper) Replaces retry sleeping, useful for deterministic tests.

The defaults are a 30-second HTTP timeout, the growth plan, the cryptopanic-go/1.0.0 User-Agent, and zero retry attempts.

Working with posts

Posts accepts a PostsQuery value. Empty fields are omitted from the request, and the client validates only rules that are safe to check locally. The CryptoPanic server remains the authority for account permissions and values that may change over time.

size := 20
pageNumber := 1

page, err := client.Posts(ctx, cryptopanic.PostsQuery{
    Currencies: []string{"BTC", "ETH", "SOL"},
    Regions:    "en",
    Kind:       cryptopanic.KindNews,
    Filter:     cryptopanic.FilterHot,
    Size:       &size,
    Page:       &pageNumber,
})
if err != nil {
    log.Fatal(err)
}

for _, post := range page.Results {
    fmt.Println(post.Title)
    if post.Source != nil {
        fmt.Println("source:", post.Source.Title)
    }
}
Query fields
Field Type What it does Plan note
Public *bool Requests public mode when set. All listed plans
Currencies []string Sends a comma-separated list such as BTC,ETH. All listed plans
Regions string Sets a region code; the API default is en. All listed plans
Filter Filter Known values include rising, hot, bullish, bearish, important, saved, and lol. Custom values are allowed. All listed plans
Kind Kind news, media, or all. All listed plans
Following *bool Private-only following mode. All listed plans
LastPull *time.Time Sends an RFC 3339 / ISO-8601 timestamp. Enterprise-gated
PanicPeriod PanicPeriod 1h, 6h, or 24h. Enterprise-gated
PanicSort PanicSort asc or desc; requires PanicPeriod locally. Enterprise-gated
Size *int Page size from 1 through 50. Enterprise-gated
Page *int Page number from 1 through 50; the API default is 1. All listed plans
WithContent *bool Requests full post content. Enterprise-gated
Search string Searches for a non-empty string. Enterprise-gated

For pointer fields such as Page, Size, Public, and WithContent, use the package helpers where convenient:

page, err := client.Posts(ctx, cryptopanic.PostsQuery{
    Page:        cryptopanic.IntPtr(2),
    Size:        cryptopanic.IntPtr(25),
    WithContent: cryptopanic.BoolPtr(true),
})

Typed constants are available for filters, kinds, panic periods, panic sorting, and plans:

cryptopanic.FilterRising
cryptopanic.KindNews
cryptopanic.PanicPeriod1h
cryptopanic.PanicSortDesc
cryptopanic.PlanEnterprise

The complete set is available in the package documentation on pkg.go.dev.

Other endpoints

Portfolio

Portfolio returns PortfolioResponse.Raw as json.RawMessage. This is intentional: the public API reference does not define a complete stable portfolio schema, so the SDK preserves the server response instead of guessing at a model.

portfolio, err := client.Portfolio(ctx)
if err != nil {
    log.Fatal(err)
}

fmt.Println(string(portfolio.Raw))

Decode the raw JSON into the shape your application needs:

import "encoding/json"

var portfolioData map[string]any
if err := json.Unmarshal(portfolio.Raw, &portfolioData); err != nil {
    log.Fatal(err)
}
RSS

RSS methods return raw XML in RSSResponse.Body. They do not convert XML into PostsPage or JSON models.

feed, err := client.NewsRSS(ctx)
if err != nil {
    log.Fatal(err)
}

fmt.Println(feed.Body)

PostsRSS uses the same PostsQuery filters and adds format=rss. The public reference documents the RSS response as 20 items regardless of plan.

Supported endpoints

The CryptoPanic public API documentation uses one shared API Reference page, so the links below intentionally point to the same page.

Endpoint Go method Return value
GET /posts/ client.Posts(ctx, query) *PostsPage
GET /portfolio/ client.Portfolio(ctx) *PortfolioResponse
GET /posts/?format=rss client.PostsRSS(ctx, query) *RSSResponse
GET /news/rss/ client.NewsRSS(ctx) *RSSResponse

See the CryptoPanic API reference and plans page for server-side behavior.

Response models

PostsPage
Field Meaning
Results Posts returned for the current page.
Next / Previous Redacted pagination URLs; empty when unavailable.
HasNext / HasPrevious Whether another page exists.
NextPage / PreviousPage Page numbers extracted from the pagination URLs, when present.
Post

A post includes its ID, slug, title, description, publication and creation timestamps, kind, source, original URL, CryptoPanic URL, image, tagged instruments, votes, author, and optional content. Enterprise-gated or potentially omitted values are pointers, so check them before use:

for _, post := range page.Results {
    fmt.Println(post.Title)

    if post.PublishedAt != nil {
        fmt.Println("published:", post.PublishedAt.Format(time.RFC3339))
    }

    if post.Content != nil {
        // Content is available only when the account and query allow it.
    }
}

Unknown additive fields from the server do not make JSON decoding fail.

Pagination

CryptoPanic returns next and previous URLs in the response envelope. The SDK exposes those URLs only after redacting the auth_token value, and extracts the page number when it is present.

The client does not accept a pagination URL directly. Request the next page using NextPage or build the next PostsQuery yourself:

page, err := client.Posts(ctx, cryptopanic.PostsQuery{Page: cryptopanic.IntPtr(1)})
if err != nil {
    log.Fatal(err)
}

for page.HasNext && page.NextPage != nil {
    next, err := client.Posts(ctx, cryptopanic.PostsQuery{
        Page: page.NextPage,
    })
    if err != nil {
        log.Fatal(err)
    }

    for _, post := range next.Results {
        fmt.Println(post.Title)
    }
    page = next
}

Errors

There are two useful ways to handle errors:

  • Use errors.Is when you need a stable category such as unauthorized, forbidden, rate-limited, or invalid query.
  • Use errors.As when you need details from APIError, such as the HTTP status, request ID, or retry count.
page, err := client.Posts(ctx, query)
if err != nil {
    switch {
    case errors.Is(err, cryptopanic.ErrMissingAuthToken):
        // Configuration is incomplete.
    case errors.Is(err, cryptopanic.ErrInvalidQuery):
        // Fix the query before sending it again.
    case errors.Is(err, cryptopanic.ErrUnauthorized):
        // 401: check the token.
    case errors.Is(err, cryptopanic.ErrForbidden):
        // 403: check access and plan permissions.
    case errors.Is(err, cryptopanic.ErrRateLimited):
        // 429: slow down or wait for the server's limit window.
    case errors.Is(err, cryptopanic.ErrServerError):
        // 500: a server-side failure.
    }

    var apiErr *cryptopanic.APIError
    if errors.As(err, &apiErr) {
        fmt.Printf("status=%d message=%s request_id=%s retried=%d\n",
            apiErr.StatusCode,
            apiErr.Message,
            apiErr.RequestID,
            apiErr.Retried,
        )
    }
}
Sentinel errors
Sentinel Meaning
ErrMissingAuthToken NewFromEnv could not find a token.
ErrInvalidQuery Local query validation failed.
ErrUnauthorized The API returned HTTP 401.
ErrForbidden The API returned HTTP 403.
ErrRateLimited The API returned HTTP 429 after retries were exhausted.
ErrServerError The API returned HTTP 500.

APIError preserves StatusCode, a human-readable Message, a redacted RawBody truncated to 512 bytes, RequestID when supplied by the server, and the number of retry attempts in Retried. The token is not included in the error string or raw body.

Transport errors and context cancellation are returned as wrapped standard-library errors, so errors.Is(err, context.DeadlineExceeded) and similar checks remain useful.

Retries and rate limits

Retries are off by default. Enable them for idempotent GET requests with WithRetryPolicy:

client := cryptopanic.New(token,
    cryptopanic.WithRetryPolicy(cryptopanic.RetryPolicy{
        MaxAttempts: 3,              // Retries after the initial request.
        BaseDelay:   500 * time.Millisecond,
        MaxDelay:    30 * time.Second,
    }),
)

The policy counts retry attempts, not total requests. MaxAttempts: 3 means up to four HTTP requests: one initial request plus three retries.

  • Retried HTTP statuses: 429, 500, 502, and 503.
  • Retried network failures: timeouts, temporary network errors, connection interruptions, and EOF-style read failures.
  • Not retried: 400, 401, 403, 404, malformed URLs, unsupported schemes, TLS certificate failures, and other permanent errors.
  • Backoff: exponential with jitter, capped by MaxDelay.
  • Server guidance: Retry-After is honored when present and capped by MaxDelay.
  • Cancellation: context cancellation stops waiting and retrying immediately.

Retries cannot fix an invalid token, an unavailable plan feature, or an invalid query. Handle those cases explicitly.

Contexts and timeouts

Every network-facing method accepts context.Context. In a web server or background worker, give each operation a deadline:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

page, err := client.Posts(ctx, cryptopanic.PostsQuery{})
if errors.Is(err, context.DeadlineExceeded) {
    // The request exceeded the caller's deadline.
}

WithTimeout sets the default timeout on the underlying http.Client. A request context is still the best way to set a shorter, operation-specific deadline or cancel work when the caller disconnects.

Custom HTTP clients and test servers

Use WithHTTPClient when your application needs a proxy, custom transport, TLS configuration, or test instrumentation:

httpClient := &http.Client{Timeout: 20 * time.Second}
client := cryptopanic.New(token, cryptopanic.WithHTTPClient(httpClient))

Use WithBaseURL with httptest.Server or another mock server. The value should not include the plan segment; an optional trailing slash is removed. The SDK appends /{plan}/v2/ automatically.

WithSleeper is available when tests need to observe retry delays without actually sleeping.

Plan caveats

The free Developer API plan was discontinued. The SDK still exposes the documented PlanDeveloper value for compatibility, but it does not claim that an account has access to it.

Parameters such as last_pull, panic_period, size, with_content, and search may be plan-gated. The SDK validates obvious syntax locally, while CryptoPanic remains the authority for account entitlements and evolving server rules. Check your account dashboard and the plans page for current commercial details.

Testing and development

Run the quality checks from the package directory:

go test ./... -v -count=1
gofmt -l .
go vet ./...

The test suite uses httptest.Server and fixtures under testdata/; it does not make live API calls. The Sleeper abstraction keeps retry tests fast and deterministic.

For local development:

git clone https://github.com/tigusigalpa/cryptopanic-go.git
cd cryptopanic-go
go test ./...

Release, security, and contribution

This project follows Semantic Versioning. See CHANGELOG.md for release history, CONTRIBUTING.md for contribution guidelines, and SECURITY.md for vulnerability reporting and credential-safety guidance.

License

MIT — See LICENSE for details.

Author

Igor Sazonov

Documentation

Overview

Package cryptopanic provides a Go SDK for the CryptoPanic API (https://cryptopanic.com/developers/api/).

The SDK exposes a configurable, context-aware Client with typed methods for the publicly documented endpoints: Posts, Portfolio, and RSS feeds. All network-facing methods accept context.Context as their first parameter.

Index

Constants

View Source
const DefaultBaseURL = "https://cryptopanic.com/api"

DefaultBaseURL is the default CryptoPanic API base URL. The {plan} segment is replaced at construction time based on the configured Plan option.

View Source
const DefaultMaxRetryAttempts = 0

DefaultMaxRetryAttempts is the default number of retry attempts (excluding the initial request) for transient failures. By default retries are disabled.

View Source
const DefaultRetryBaseDelay = 500 * time.Millisecond

DefaultRetryBaseDelay is the default initial backoff delay for retry attempts.

View Source
const DefaultRetryMaxDelay = 30 * time.Second

DefaultRetryMaxDelay is the maximum delay between retry attempts.

View Source
const DefaultTimeout = 30 * time.Second

DefaultTimeout is the default HTTP client timeout used unless overridden with WithTimeout.

View Source
const DefaultUserAgent = "cryptopanic-go/1.0.0"

DefaultUserAgent is the default User-Agent header value sent with every request.

Variables

View Source
var (
	// ErrMissingAuthToken is returned when no auth_token is provided.
	ErrMissingAuthToken = errors.New("cryptopanic: missing auth token — set CRYPTOPANIC_AUTH_TOKEN or pass a token to New")
	// ErrInvalidQuery is returned when local query validation fails.
	ErrInvalidQuery = errors.New("cryptopanic: invalid query parameters")
	// ErrUnauthorized is returned when the API responds with HTTP 401.
	ErrUnauthorized = errors.New("cryptopanic: unauthorized — check your auth token")
	// ErrForbidden is returned when the API responds with HTTP 403.
	ErrForbidden = errors.New("cryptopanic: forbidden — access or plan restriction")
	// ErrRateLimited is returned when the API responds with HTTP 429
	// and all retry attempts have been exhausted.
	ErrRateLimited = errors.New("cryptopanic: rate limit exceeded")
	// ErrServerError is returned when the API responds with HTTP 500.
	ErrServerError = errors.New("cryptopanic: server error")
)

Sentinel errors that can be checked with errors.Is against errors returned from methods. The underlying *APIError is always available via errors.As for accessing StatusCode, RawBody, etc.

Functions

func BoolPtr

func BoolPtr(b bool) *bool

BoolPtr returns a pointer to the provided bool value. Useful for populating optional pointer fields in PostsQuery.

func IntPtr

func IntPtr(i int) *int

IntPtr returns a pointer to the provided int value.

func StringPtr

func StringPtr(s string) *string

StringPtr returns a pointer to the provided string value.

func TimePtr

func TimePtr(t time.Time) *time.Time

TimePtr returns a pointer to the provided time.Time value.

Types

type APIError

type APIError struct {
	// StatusCode is the HTTP status code returned by the API.
	StatusCode int
	// Message is a human-readable error message extracted from the
	// response body or a generated fallback.
	Message string
	// RawBody contains a truncated, redacted copy of the raw response
	// body for debugging purposes (max 512 bytes).
	RawBody []byte
	// RequestID is the value of the X-Request-ID response header, if
	// the server provides one.
	RequestID string
	// Retried is the number of retry attempts made before this error
	// was returned.
	Retried int
}

APIError represents an error response returned by the CryptoPanic API. It is returned by every method when the API responds with a non-2xx HTTP status code. The error carries the status code, a safe response excerpt, and the request ID when available, but never includes the auth_token or a full sensitive request URL.

func (*APIError) Error

func (e *APIError) Error() string

Error implements the error interface for APIError.

type Client

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

Client is the entry point of the CryptoPanic Go SDK. It holds HTTP configuration and exposes methods for the publicly documented API endpoints. A Client is safe for concurrent use by multiple goroutines.

func New

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

New creates a new CryptoPanic API client authenticated with the given auth_token. Behaviour can be customized via Option values such as WithPlan, WithBaseURL, WithHTTPClient, WithTimeout, WithRetryPolicy, and WithUserAgent.

The auth_token is sent as the auth_token query parameter on every request, as required by the CryptoPanic API. It is never placed in a URL path, user agent, error message, or log record.

func NewFromEnv

func NewFromEnv(opts ...Option) (*Client, error)

NewFromEnv reads the auth_token from the CRYPTOPANIC_AUTH_TOKEN environment variable and returns a new CryptoPanic client. Additional Option values can be passed to override plan, timeouts, retries, etc.

func (*Client) NewsRSS

func (c *Client) NewsRSS(ctx context.Context) (*RSSResponse, error)

NewsRSS retrieves the public CryptoPanic RSS news feed (GET /news/rss/). This is a public endpoint that does not require authentication, but the auth_token is still sent as documented. Returns raw RSS XML content.

Documentation: https://cryptopanic.com/developers/api/

func (*Client) Portfolio

func (c *Client) Portfolio(ctx context.Context) (*PortfolioResponse, error)

Portfolio retrieves the authenticated user's portfolio from the CryptoPanic API (GET /portfolio/). This endpoint is available under Growth and Enterprise plans according to the public reference.

Because the public API reference does not specify a complete response schema, the response is returned as an opaque PortfolioResponse containing the raw decoded JSON. No domain model is fabricated.

Documentation: https://cryptopanic.com/developers/api/

func (*Client) Posts

func (c *Client) Posts(ctx context.Context, query PostsQuery) (*PostsPage, error)

Posts retrieves a paginated list of news posts from the CryptoPanic API (GET /posts/). The query object controls filtering, currencies, regions, kind, pagination, and enterprise-gated parameters.

The auth_token is injected from the client configuration and never passed in the query object. Pagination URLs in the response are redacted: any auth_token parameter is removed before exposure.

Documentation: https://cryptopanic.com/developers/api/

func (*Client) PostsRSS

func (c *Client) PostsRSS(ctx context.Context, query PostsQuery) (*RSSResponse, error)

PostsRSS retrieves the posts endpoint with format=rss, returning raw RSS XML content. The reference says format=rss returns 20 items regardless of plan. RSS content is preserved as XML and is not coerced into the JSON post page type.

Documentation: https://cryptopanic.com/developers/api/

type Filter

type Filter string

Filter represents a known posts filter value. The CryptoPanic API documents filters such as rising, hot, bullish, bearish, important, saved, and lol. Custom string values are allowed for forward compatibility.

const (
	FilterRising    Filter = "rising"
	FilterHot       Filter = "hot"
	FilterBullish   Filter = "bullish"
	FilterBearish   Filter = "bearish"
	FilterImportant Filter = "important"
	FilterSaved     Filter = "saved"
	FilterLol       Filter = "lol"
)

Filter values identify the documented post-filter options.

type Kind

type Kind string

Kind represents a known posts kind value.

const (
	KindNews  Kind = "news"
	KindMedia Kind = "media"
	KindAll   Kind = "all"
)

Kind values identify the documented post kinds.

type Option

type Option func(*Client)

Option configures a Client. Options are applied in the order they are passed to New.

func WithBaseURL

func WithBaseURL(url string) Option

WithBaseURL overrides the default CryptoPanic API base URL. This is primarily useful for testing against a mock server. The URL should not include the plan segment; an optional trailing slash is removed. The SDK appends /{plan}/v2/ automatically.

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient sets a custom *http.Client used to perform requests. This allows callers to configure transport-level behaviour such as proxies, TLS settings, or custom RoundTrippers.

func WithPlan

func WithPlan(plan Plan) Option

WithPlan sets the API plan segment used in the base URL. The default is PlanGrowth. Valid values are PlanDeveloper, PlanGrowth, and PlanEnterprise. Check the plans page at https://cryptopanic.com/developers/api/plans for commercial details.

func WithRetryPolicy

func WithRetryPolicy(policy RetryPolicy) Option

WithRetryPolicy configures automatic retry behaviour for idempotent GET requests. Retries are applied for transient network failures, HTTP 429, and selected 5xx responses. The Retry-After header is honored when present. Exponential backoff with jitter is used otherwise. Retries are disabled by default.

func WithSleeper

func WithSleeper(s Sleeper) Option

WithSleeper sets a custom Sleeper used for retry delays. This is primarily useful for testing to avoid real delays.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the timeout applied to the underlying HTTP client for every request made by the Client.

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent sets the User-Agent header value. The SDK name and version are included by default; this option overrides the entire value.

type PanicPeriod

type PanicPeriod string

PanicPeriod represents a known panic period value.

const (
	PanicPeriod1h  PanicPeriod = "1h"
	PanicPeriod6h  PanicPeriod = "6h"
	PanicPeriod24h PanicPeriod = "24h"
)

PanicPeriod values identify the supported panic-score time windows.

type PanicSort

type PanicSort string

PanicSort represents a known panic sort direction.

const (
	PanicSortAsc  PanicSort = "asc"
	PanicSortDesc PanicSort = "desc"
)

PanicSort values identify the supported panic-score sort directions.

type Plan

type Plan string

Plan represents a CryptoPanic API plan segment used in the base URL.

const (
	// PlanDeveloper is the developer plan segment. Note: the free
	// Developer API plan was discontinued. Check your account dashboard
	// and the plans page for current commercial details.
	PlanDeveloper Plan = "developer"
	// PlanGrowth is the growth plan segment.
	PlanGrowth Plan = "growth"
	// PlanEnterprise is the enterprise plan segment.
	PlanEnterprise Plan = "enterprise"
)

type PortfolioResponse

type PortfolioResponse struct {
	// Raw contains the original decoded JSON from the portfolio
	// endpoint response.
	Raw json.RawMessage `json:"-"`
}

PortfolioResponse is an opaque/generic wrapper for the GET /portfolio/ endpoint. The public API reference does not specify a complete response schema, so the raw decoded JSON is retained instead of fabricating a domain model. Future schema expansion is backward compatible because callers access data through the Raw field.

type Post

type Post struct {
	// ID is the unique numeric post identifier.
	ID int `json:"id"`
	// Slug is the URL-friendly post slug.
	Slug string `json:"slug"`
	// Title is the post title.
	Title string `json:"title"`
	// Description is the post description/summary.
	Description string `json:"description"`
	// PublishedAt is the publication timestamp.
	PublishedAt *time.Time `json:"published_at"`
	// CreatedAt is the post creation timestamp.
	CreatedAt *time.Time `json:"created_at"`
	// Kind is the post kind (news, media).
	Kind string `json:"kind"`
	// Source is the source object.
	Source *PostSource `json:"source"`
	// OriginalURL is the original article URL.
	OriginalURL string `json:"original_url"`
	// URL is the CryptoPanic post URL.
	URL string `json:"url"`
	// Image is the post image URL (optional).
	Image *string `json:"image"`
	// Instruments is the list of tagged instruments.
	Instruments []PostInstrument `json:"instruments"`
	// Votes is the vote counts object.
	Votes *PostVotes `json:"votes"`
	// PanicScore is the overall panic score (optional/enterprise-gated).
	PanicScore *int `json:"panic_score"`
	// PanicScore1h is the 1-hour panic score (optional/enterprise-gated).
	PanicScore1h *int `json:"panic_score_1h"`
	// Author is the post author (optional).
	Author *PostAuthor `json:"author"`
	// Content is the post content (optional/enterprise-gated).
	Content *PostContent `json:"content"`
}

Post represents a single news post in the CryptoPanic API response. Plan-gated or potentially omitted fields are nullable/optional. Additive fields sent by the service are not rejected.

type PostAuthor

type PostAuthor struct {
	// ID is the numeric author identifier.
	ID int `json:"id"`
	// Name is the display name of the author.
	Name string `json:"name"`
	// Slug is the URL-friendly author slug.
	Slug string `json:"slug"`
	// URL is the author's profile URL.
	URL string `json:"url"`
	// Avatar is the author's avatar URL.
	Avatar string `json:"avatar"`
	// Twitter is the author's Twitter handle.
	Twitter string `json:"twitter"`
	// Facebook is the author's Facebook profile.
	Facebook string `json:"facebook"`
	// LinkedIn is the author's LinkedIn profile.
	LinkedIn string `json:"linkedin"`
}

PostAuthor represents the author of a post.

type PostContent

type PostContent struct {
	// Raw is the raw content text.
	Raw string `json:"raw"`
}

PostContent represents the content object nested in a post. This field is enterprise-gated and may be null or absent.

type PostInstrument

type PostInstrument struct {
	// ID is the numeric instrument identifier.
	ID int `json:"id"`
	// Code is the instrument ticker code, e.g. BTC.
	Code string `json:"code"`
	// Slug is the URL-friendly instrument slug.
	Slug string `json:"slug"`
	// Title is the display name of the instrument.
	Title string `json:"title"`
	// Volume is the 24-hour trading volume.
	Volume float64 `json:"volume"`
	// Change is the 24-hour price change percentage.
	Change float64 `json:"change"`
	// Currency is the currency code.
	Currency string `json:"currency"`
}

PostInstrument represents a currency instrument tagged on a post.

type PostSource

type PostSource struct {
	// Title is the display title of the source.
	Title string `json:"title"`
	// Region is the region code of the source.
	Region string `json:"region"`
	// Domain is the domain name of the source.
	Domain string `json:"domain"`
	// Path is the URL path of the source article.
	Path string `json:"path"`
	// CreatedAt is the source creation timestamp.
	CreatedAt *time.Time `json:"created_at"`
}

PostSource represents the source object nested in a Post.

type PostVotes

type PostVotes struct {
	// Positive is the count of positive votes.
	Positive int `json:"positive"`
	// Negative is the count of negative votes.
	Negative int `json:"negative"`
	// Important is the count of important votes.
	Important int `json:"important"`
	// Liked is the count of liked votes.
	Liked int `json:"liked"`
	// Disliked is the count of disliked votes.
	Disliked int `json:"disliked"`
	// Lol is the count of lol votes.
	Lol int `json:"lol"`
	// Toxic is the count of toxic votes.
	Toxic int `json:"toxic"`
	// Comments is the count of comments.
	Comments int `json:"comments"`
	// Saved is the count of saved votes.
	Saved int `json:"saved"`
}

PostVotes represents the vote counts on a post.

type PostsPage

type PostsPage struct {
	// Results is the list of posts on the current page.
	Results []Post `json:"results"`
	// Next is the redacted URL for the next page, or empty if there
	// is no next page.
	Next string `json:"-"`
	// Previous is the redacted URL for the previous page, or empty if
	// there is no previous page.
	Previous string `json:"-"`
	// HasNext indicates whether a next page exists.
	HasNext bool `json:"-"`
	// HasPrevious indicates whether a previous page exists.
	HasPrevious bool `json:"-"`
	// NextPage extracts the page number from the next URL, if available.
	NextPage *int `json:"-"`
	// PreviousPage extracts the page number from the previous URL, if available.
	PreviousPage *int `json:"-"`
}

PostsPage represents the paginated envelope returned by GET /posts/. The Next and Previous fields are redacted: any auth_token query parameter is removed before exposure.

type PostsQuery

type PostsQuery struct {
	// Public is an optional boolean for public mode.
	Public *bool
	// Currencies is an optional list encoded as a comma-separated
	// set, e.g. BTC,ETH.
	Currencies []string
	// Regions is an optional region code or supported region
	// collection. Default is "en".
	Regions string
	// Filter is an optional known filter. Custom values are allowed.
	Filter Filter
	// Kind is an optional known kind. Default is "all".
	Kind Kind
	// Following is an optional boolean for strictly private usage.
	Following *bool
	// LastPull is an optional RFC 3339 / ISO-8601 timestamp.
	// Enterprise-gated in the reference.
	LastPull *time.Time
	// PanicPeriod is an optional panic period (1h, 6h, 24h).
	// Enterprise-gated in the reference.
	PanicPeriod PanicPeriod
	// PanicSort is an optional sort direction (asc, desc). Rejected
	// locally when PanicPeriod is absent. Enterprise-gated.
	PanicSort PanicSort
	// Size is an optional integer in the inclusive range 1–50.
	// Enterprise-gated in the reference.
	Size *int
	// Page is an optional integer in the inclusive range 1–50.
	// Default is 1.
	Page *int
	// WithContent is an optional boolean.
	// Enterprise-gated in the reference.
	WithContent *bool
	// Search is an optional non-empty search string.
	// Enterprise-gated in the reference.
	Search string
}

PostsQuery holds the query parameters for the GET /posts/ endpoint. Authentication is configured on the Client, not in the query object. Only clear client-side syntax and cross-field rules are validated; the CryptoPanic server remains the authority for plan eligibility and evolving allowed values.

func (*PostsQuery) ToValues

func (q *PostsQuery) ToValues() url.Values

ToValues converts the PostsQuery into url.Values suitable for use with the HTTP transport. Zero/empty values are omitted.

func (*PostsQuery) Validate

func (q *PostsQuery) Validate() error

Validate checks local client-side syntax and cross-field rules. The CryptoPanic server remains the authority for plan eligibility.

type RSSResponse

type RSSResponse struct {
	// Body contains the raw RSS XML content.
	Body string
}

RSSResponse represents a raw RSS feed response. The body is preserved as raw text/XML rather than being coerced into the JSON post page type.

type ResponseMetadata

type ResponseMetadata struct {
	// StatusCode is the HTTP status code.
	StatusCode int
	// RequestID is the value of the X-Request-ID header, if present.
	RequestID string
	// Duration is the time taken for the HTTP round-trip.
	Duration time.Duration
}

ResponseMetadata holds non-body information from an HTTP response.

type RetryPolicy

type RetryPolicy struct {
	// MaxAttempts is the maximum number of retry attempts (excluding
	// the initial request). Set to 0 to disable retries.
	MaxAttempts int
	// BaseDelay is the initial backoff delay.
	BaseDelay time.Duration
	// MaxDelay caps the delay between retries.
	MaxDelay time.Duration
}

RetryPolicy controls the retry behaviour for idempotent GET requests. Retries are disabled by default (MaxAttempts = 0).

type Sleeper

type Sleeper interface {
	Sleep(d time.Duration) bool
}

Sleeper is an interface for sleeping between retry attempts. It allows tests to control timing without real delays.

Directories

Path Synopsis
examples
basic command
filter command
pagination command
portfolio command
rss command

Jump to

Keyboard shortcuts

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