Get one signal with its complete evidence bundle
curl --request GET \
--url http://localhost:3101/api/signals/{id}import requests
url = "http://localhost:3101/api/signals/{id}"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('http://localhost:3101/api/signals/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "3101",
CURLOPT_URL => "http://localhost:3101/api/signals/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "http://localhost:3101/api/signals/{id}"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("http://localhost:3101/api/signals/{id}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:3101/api/signals/{id}")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"signal": {
"version": "<string>",
"signal_id": "<string>",
"target": {
"chain": "<string>",
"address": "<string>"
},
"verdict": "avoid",
"confidence": 123,
"reasoning": "<string>",
"evidence_used": [
"<string>"
],
"evidence_hash": "<string>",
"prompt_version": "<string>",
"model": "<string>",
"generated_at": "2023-11-07T05:31:56Z",
"generated_at_unix": 123,
"call_hash": "<string>",
"anchor_tx": "<string>",
"anchor_status": "<string>",
"anchor_chain_id": 123,
"cost_usd": 123,
"cached": true,
"run_id": "<string>",
"evidence_source_count": 123
},
"evidence_summary": {
"source_count": 123,
"present": 123,
"gaps": [
{
"source": "<string>",
"status": "unavailable",
"reason": "<string>"
}
],
"citable_key_count": 123
},
"read_this_first": {
"gaps": "<string>",
"anchoring": "<string>",
"not_advice": "<string>"
}
}{
"error": "not_found",
"signal_id": "<string>",
"detail": "<string>"
}Public HTTP endpoints
Get a signal
One signal with its complete evidence bundle, including the sources that produced nothing and why.
GET
/
api
/
signals
/
{id}
Get one signal with its complete evidence bundle
curl --request GET \
--url http://localhost:3101/api/signals/{id}import requests
url = "http://localhost:3101/api/signals/{id}"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('http://localhost:3101/api/signals/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "3101",
CURLOPT_URL => "http://localhost:3101/api/signals/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "http://localhost:3101/api/signals/{id}"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("http://localhost:3101/api/signals/{id}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:3101/api/signals/{id}")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"signal": {
"version": "<string>",
"signal_id": "<string>",
"target": {
"chain": "<string>",
"address": "<string>"
},
"verdict": "avoid",
"confidence": 123,
"reasoning": "<string>",
"evidence_used": [
"<string>"
],
"evidence_hash": "<string>",
"prompt_version": "<string>",
"model": "<string>",
"generated_at": "2023-11-07T05:31:56Z",
"generated_at_unix": 123,
"call_hash": "<string>",
"anchor_tx": "<string>",
"anchor_status": "<string>",
"anchor_chain_id": 123,
"cost_usd": 123,
"cached": true,
"run_id": "<string>",
"evidence_source_count": 123
},
"evidence_summary": {
"source_count": 123,
"present": 123,
"gaps": [
{
"source": "<string>",
"status": "unavailable",
"reason": "<string>"
}
],
"citable_key_count": 123
},
"read_this_first": {
"gaps": "<string>",
"anchoring": "<string>",
"not_advice": "<string>"
}
}{
"error": "not_found",
"signal_id": "<string>",
"detail": "<string>"
}The endpoint that makes the feed checkable
This returns everything the model was shown — including the sources that produced nothing, and the reason each one produced nothing. That distinction is the entire point. “The rug scorer found no problem” and “the rug scorer was not installed on that host” support very different readings of the same verdict, and only the bundle tells them apart.Reading evidence_summary.gaps
{
"evidence_summary": {
"source_count": 6,
"present": 2,
"gaps": [
{
"source": "memecoin_packet",
"status": "unavailable",
"reason": "module not installed on this deployment"
}
],
"citable_key_count": 14
}
}
A verdict of
no_opinion on a signal with four gaps is the system working correctly. The verifier rejects any verdict the surviving evidence cannot support, so on a deployment missing the memecoin collectors, every memecoin bundle is empty by design and every verdict except no_opinion is refused.status | Meaning |
|---|---|
present | The source contributed citable evidence |
unavailable | The source is not installed on this deployment |
dormant | Installed, but has produced no data yet |
error | The source was called and failed. The reason is recorded |
read_this_first
Every response carries a block that states, in prose, the three things a consumer most often gets wrong: whether there are evidence gaps, whether the signal is genuinely anchored on-chain, and that a verdict is not advice. It is part of the payload rather than the docs because a payload travels to places documentation does not.
Next step
Pair this with verification, which re-derives the hashes from this exact payload using an independent implementation.Scienter publishes impersonal market signals of general and regular circulation. Nothing here is investment, legal, or tax advice, or a recommendation to buy, sell, or hold any asset. Scienter is not a registered investment adviser or broker-dealer. Trading digital assets can result in the total loss of your funds — see Disclaimers for the full text.