Documentation Index Fetch the complete documentation index at: https://developer.alterscope.org/llms.txt
Use this file to discover all available pages before exploring further.
There is no first-party Go SDK yet. The API is plain HTTPS + JSON, so calling it from Go takes a small net/http wrapper. This walks a Go 1.22+ developer through install, Bearer auth, one REST call with the agentic envelope, a WebSocket stream, and a retry helper. Expect about five minutes end-to-end.
The full program is checked in at sdks/go/examples/quickstart/main.go — what follows is the same code, broken into steps.
1. Initialize the module
mkdir alterscope-quickstart && cd alterscope-quickstart
go mod init example.com/alterscope-quickstart
go get github.com/gorilla/websocket@v1.5.1
Go 1.22+ is required.
2. Define the response types
The agentic envelope is the same on every v2 endpoint — define it once and embed it in any specific response struct.
// AgenticFreshness mirrors response.meta._agentic.freshness.
// status is one of "realtime" | "fresh" | "stale" | "unknown".
type AgenticFreshness struct {
ComputedAt string `json:"computed_at"`
AgeSeconds float64 `json:"age_seconds"`
UpdateCadenceSeconds float64 `json:"update_cadence_seconds"`
Status string `json:"status"`
ShouldRetry bool `json:"should_retry"`
}
type AgenticQualityGate struct {
Verdict string `json:"verdict"` // "pass" | "warn" | "fail"
DegradedFields [] string `json:"degraded_fields,omitempty"`
}
type AgenticMeta struct {
SchemaVersion string `json:"schema_version"`
Confidence float64 `json:"confidence"`
Freshness * AgenticFreshness `json:"freshness,omitempty"`
QualityGate * AgenticQualityGate `json:"quality_gate,omitempty"`
}
type OracleClassificationResponse struct {
Data json . RawMessage `json:"data"`
Meta struct {
Agentic * AgenticMeta `json:"_agentic,omitempty"`
} `json:"meta"`
}
3. Build the client
The two things every call needs: a Bearer header and a retry loop.
const (
defaultBaseURL = "https://dev.alterscope.org/api"
maxRetries = 3
requestTimeout = 30 * time . Second
)
type Client struct {
BaseURL string
APIKey string
HTTPClient * http . Client
}
func New () ( * Client , error ) {
apiKey := os . Getenv ( "ALTERSCOPE_API_KEY" )
if apiKey == "" {
return nil , errors . New ( "ALTERSCOPE_API_KEY env var is required" )
}
baseURL := os . Getenv ( "ALTERSCOPE_BASE_URL" )
if baseURL == "" {
baseURL = defaultBaseURL
}
return & Client {
BaseURL : baseURL ,
APIKey : apiKey ,
HTTPClient : & http . Client { Timeout : requestTimeout },
}, nil
}
// Do issues an authenticated request with retry on 429/5xx.
// Honors Retry-After on 429; otherwise exponential backoff capped at 60s.
func ( c * Client ) Do ( ctx context . Context , method , path string ) ( * http . Response , error ) {
var lastErr error
for attempt := 0 ; attempt < maxRetries ; attempt ++ {
req , err := http . NewRequestWithContext ( ctx , method , c . BaseURL + path , nil )
if err != nil {
return nil , err
}
req . Header . Set ( "Authorization" , "Bearer " + c . APIKey )
req . Header . Set ( "Accept" , "application/json" )
resp , err := c . HTTPClient . Do ( req )
if err != nil {
lastErr = err
time . Sleep ( backoff ( attempt , nil ))
continue
}
if resp . StatusCode == http . StatusTooManyRequests || resp . StatusCode >= 500 {
delay := backoff ( attempt , resp )
_ = resp . Body . Close ()
if attempt == maxRetries - 1 {
return nil , fmt . Errorf ( "alterscope: %s after %d attempts" , resp . Status , maxRetries )
}
time . Sleep ( delay )
continue
}
return resp , nil
}
return nil , fmt . Errorf ( "alterscope: request failed: %w " , lastErr )
}
func backoff ( attempt int , resp * http . Response ) time . Duration {
if resp != nil && resp . StatusCode == http . StatusTooManyRequests {
if ra := resp . Header . Get ( "Retry-After" ); ra != "" {
if secs , err := strconv . Atoi ( ra ); err == nil {
return time . Duration ( secs ) * time . Second
}
}
}
d := time . Duration ( math . Pow ( 2 , float64 ( attempt ))) * time . Second
if d > 60 * time . Second {
d = 60 * time . Second
}
return d
}
4. Your first call
The cheapest “is it working?” call is an oracle classification — the response always includes the agentic envelope, so you can confirm auth + parsing are correct in one round-trip.
func ( c * Client ) ClassifyOracle ( ctx context . Context , marketID string ) ( * OracleClassificationResponse , error ) {
resp , err := c . Do ( ctx , http . MethodGet , "/v2/oracle/" + url . PathEscape ( marketID ) + "/classification" )
if err != nil {
return nil , err
}
defer resp . Body . Close ()
body , err := io . ReadAll ( resp . Body )
if err != nil {
return nil , fmt . Errorf ( "read body: %w " , err )
}
if resp . StatusCode != http . StatusOK {
return nil , fmt . Errorf ( "alterscope: %s : %s " , resp . Status , string ( body ))
}
var out OracleClassificationResponse
if err := json . Unmarshal ( body , & out ); err != nil {
return nil , fmt . Errorf ( "decode response: %w " , err )
}
return & out , nil
}
func main () {
client , err := New ()
if err != nil {
log . Fatal ( err )
}
ctx , cancel := context . WithTimeout ( context . Background (), 60 * time . Second )
defer cancel ()
resp , err := client . ClassifyOracle ( ctx ,
"0x3a85e619b69e7a0c4dd158d61eb41e95b6f25cf3aa3c0f1e5f6e7d8c9b0a1d2f" )
if err != nil {
log . Fatal ( err )
}
if a := resp . Meta . Agentic ; a != nil {
fmt . Printf ( "schema_version: %s \n " , a . SchemaVersion )
fmt . Printf ( "confidence: %.2f \n " , a . Confidence )
if a . Freshness != nil {
fmt . Printf ( "freshness: %s (age= %.0f s) \n " , a . Freshness . Status , a . Freshness . AgeSeconds )
}
if a . QualityGate != nil {
fmt . Printf ( "quality: %s \n " , a . QualityGate . Verdict )
}
}
}
Expected first-call output (real shape — values vary per market and run):
schema_version: 2.0.0
confidence: 0.94
freshness: fresh (age=42s)
quality: pass
Freshness.Status is one of "realtime", "fresh", "stale", or "unknown". Treat stale as a soft-error in your agent loop — re-fetch before acting on the data.
5. Stream events
Risk events are pushed over a WebSocket. Authenticate with the same API key as a ?token= query parameter.
func streamOracleFailures ( ctx context . Context , apiKey string ) error {
dialURL := "wss://dev.alterscope.org/ws?token=" + url . QueryEscape ( apiKey )
ws , _ , err := websocket . DefaultDialer . DialContext ( ctx , dialURL , nil )
if err != nil {
return fmt . Errorf ( "dial ws: %w " , err )
}
defer ws . Close ()
if err := ws . WriteJSON ( map [ string ] any {
"type" : "subscribe" ,
"channel" : "events" ,
"event_types" : [] string { "oracle_failure" , "exploit" },
}); err != nil {
return fmt . Errorf ( "write subscribe: %w " , err )
}
for {
var msg map [ string ] any
if err := ws . ReadJSON ( & msg ); err != nil {
return fmt . Errorf ( "read ws: %w " , err )
}
if msg [ "type" ] == "market_event" && msg [ "event_type" ] == "oracle_failure" {
fmt . Printf ( "oracle failure on %v : %v \n " , msg [ "protocol" ], msg [ "title" ])
}
}
}
Channel / event-type reference: WebSockets API .
6. Receive a webhook
Webhooks are plain HTTPS POSTs with a JSON body. Until signature verification ships, restrict the receiver to source IPs you control.
http . HandleFunc ( "/alterscope-webhook" , func ( w http . ResponseWriter , r * http . Request ) {
body , err := io . ReadAll ( r . Body )
if err != nil {
http . Error ( w , "read body" , http . StatusBadRequest )
return
}
var event struct {
Type string `json:"type"`
Data json . RawMessage `json:"data"`
}
if err := json . Unmarshal ( body , & event ); err != nil {
http . Error ( w , "bad json" , http . StatusBadRequest )
return
}
log . Printf ( " %s : %s " , event . Type , event . Data )
w . WriteHeader ( http . StatusNoContent )
})
log . Fatal ( http . ListenAndServe ( ":8080" , nil ))
Signature verification ships with the GA SDK release. Until then, restrict the webhook URL to source IPs you control and rotate the secret if it leaks. Track via the changelog .
Run it
go mod tidy
ALTERSCOPE_API_KEY = sk_live_... go run main.go
The full single-file version is at sdks/go/examples/quickstart/main.go .
Next steps
Pricing & quotas Free, Pro, Pro+, and Enterprise tiers — what each gets you.
Changelog What changed in the API and SDKs, week by week.
API Reference Every operation with try-it-out.
Recipes End-to-end flows: depeg detection, scoring, treasury automation.