Typed response models
Every method returns a typed model parsed out of the success/data envelope, so you never index into a raw dict. The original payload stays reachable, which means a field the API adds later is not lost.
Python, JavaScript/TypeScript, PHP and Go, published to their own registries and built against the same API contract. Typed models, typed errors, and backoff that honours Retry-After — so the only code you write is the code that uses the data.
Two lines to a typed value
The client reads the key from the environment, so nothing about the key appears in your code.
from tickatlas import TickAtlas client = TickAtlas() ind = client.get_indicator("EURUSD", "RSI_14", timeframe="H1") print(ind.value) # 58.43
Each package is published independently to its own registry from a single monorepo, so the four move together but install the way your ecosystem expects.
| Language | Package | Registry | Requires |
|---|---|---|---|
| Python | tickatlas | PyPI | Python 3.9+ |
| JavaScript / TypeScript | tickatlas | npm | Node 18+, or a modern browser |
| PHP | tickatlas/php-sdk | Packagist | PHP 8.1+ |
| Go | github.com/abuzant/tickatlas-sdk/go | Go modules | Go 1.21+ |
Exact ids matter: the PHP package is tickatlas/php-sdk, and the Go
module path ends in /go because the repository is a monorepo.
All four clients resolve the key in the same order: an explicit constructor
argument, then TICKATLAS_API_KEY, then failure at construction
time — which is a better place to find out than a 401 in production.
X-API-Key request header. tk_. Create one in the dashboard. TICKATLAS_BASE_URL repoints a client without a code change. export TICKATLAS_API_KEY="tk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # Optional — point a client at staging or a self-hosted deployment export TICKATLAS_BASE_URL="https://tickatlas.com/v1"
A sync TickAtlas client and an async AsyncTickAtlas with an identical surface. Fully typed and ships py.typed, so your editor and mypy see the models. One runtime dependency: httpx.
Source and the full per-endpoint reference: github.com/abuzant/tickatlas-sdk/python
from tickatlas import TickAtlas
with TickAtlas() as client: # reads TICKATLAS_API_KEY
quote = client.get_quote("EURUSD")
print(quote.symbol, quote.bid, quote.ask, quote.spread_pips)
ind = client.get_indicator("EURUSD", "RSI_14", timeframe="H1")
print(ind.value, ind.updated_at)
summary = client.get_summary("EURUSD", timeframe="H4")
print(summary.bias, summary.bias_strength, summary.confidence)
screen = client.screen("RSI_14", timeframe="H1", max_val=30, limit=50)
for r in screen.results:
print(r.symbol, r.value) import asyncio
from tickatlas import AsyncTickAtlas
async def main():
async with AsyncTickAtlas() as client:
quote, summary = await asyncio.gather(
client.get_quote("EURUSD"),
client.get_summary("EURUSD", timeframe="H4"),
)
print(quote.bid, summary.bias)
asyncio.run(main()) from tickatlas import (
TickAtlas,
TickAtlasError,
AuthenticationError,
NotFoundError,
RateLimitError,
ValidationError,
)
client = TickAtlas()
try:
client.get_quote("NOPE")
except NotFoundError as e:
print(e.status_code, e.code, e.message)
except RateLimitError as e:
print("back off for", e.retry_after)
except (AuthenticationError, ValidationError) as e:
print("fix the request:", e.code)
except TickAtlasError:
raise TypeScript source shipped as ESM, CommonJS and full declarations. Zero runtime dependencies — it uses the platform fetch, which is why Node 18 is the floor.
Source and the full per-endpoint reference: github.com/abuzant/tickatlas-sdk/javascript
import { TickAtlas, Indicators, Timeframes } from "tickatlas";
const client = new TickAtlas({ apiKey: process.env.TICKATLAS_API_KEY });
const quote = await client.getQuote("EURUSD");
console.log(`${quote.symbol}: ${quote.bid} / ${quote.ask} (${quote.spread_pips} pips)`);
const rsi = await client.getIndicator("EURUSD", Indicators.RSI_14, {
timeframe: Timeframes.H1,
});
console.log(rsi.value);
const strength = await client.getHeatmap({ type: "strength", timeframe: "H4" });
console.log(strength.strongest, strength.weakest);
const batch = await client.getQuotes(["EURUSD", "GBPUSD", "XAUUSD"], ["bid", "ask"]);
console.log(batch.count, batch.quotes); A Composer package with readonly response models and a typed exception tree. Because PHP’s Exception::getCode() is final and integer-only, the string error.code is exposed as getErrorCode().
Source and the full per-endpoint reference: github.com/abuzant/tickatlas-sdk/php
<?php
require 'vendor/autoload.php';
use TickAtlas\Client;
use TickAtlas\Exception\NotFoundException;
use TickAtlas\Exception\RateLimitException;
use TickAtlas\Exception\TickAtlasException;
$client = new Client(); // reads TICKATLAS_API_KEY
try {
$quote = $client->getQuote('EURUSD');
printf("EURUSD bid=%s ask=%s spread=%s pips\n",
$quote->bid, $quote->ask, $quote->spreadPips);
$rsi = $client->getIndicator('EURUSD', 'RSI_14', ['timeframe' => 'H1']);
printf("RSI(14) = %s\n", $rsi->value);
} catch (NotFoundException $e) {
echo $e->getErrorCode(), "\n"; // the string error.code
} catch (RateLimitException $e) {
echo "retry after ", $e->retryAfter, "s\n";
} catch (TickAtlasException $e) {
fwrite(STDERR, $e->getMessage() . "\n");
} Standard library only — net/http, encoding/json, context, and nothing else. Functional options, a context.Context first argument on every call, and typed results and errors.
Source and the full per-endpoint reference: github.com/abuzant/tickatlas-sdk/go
package main
import (
"context"
"fmt"
"log"
tickatlas "github.com/abuzant/tickatlas-sdk/go"
)
func main() {
client, err := tickatlas.NewClient() // reads TICKATLAS_API_KEY
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
quote, err := client.Quote(ctx, "EURUSD", nil)
if err != nil {
log.Fatal(err)
}
if quote.Bid != nil {
fmt.Printf("%s bid=%.5f ask=%.5f\n", quote.Symbol, *quote.Bid, *quote.Ask)
}
rsi, err := client.Indicator(ctx, "EURUSD", tickatlas.RSI14,
&tickatlas.IndicatorParams{Timeframe: tickatlas.TimeframeH1})
if err != nil {
log.Fatal(err)
}
if rsi.Value != nil {
fmt.Printf("RSI(14) = %.2f\n", *rsi.Value)
}
}
Not a popular subset — every route under /v1, including the one
write route. Each package also wraps the unauthenticated /health
probe.
| Group | Method | Route | Returns |
|---|---|---|---|
| Symbols | GET | /v1/symbols | Instrument list with category, digits and base/quote currency. |
| GET | /v1/symbols/{symbol} | One instrument’s full contract specification. | |
| Quotes | GET | /v1/quote | Bid, ask, spread and spread_pips for one symbol. |
| POST | /v1/quotes | Many symbols in one body, with a not_found list for the misses. | |
| History | GET | /v1/ohlc | OHLCV candles for a symbol and timeframe. |
| GET | /v1/ticks | Raw tick bid/ask over a bounded window. | |
| Indicators | GET | /v1/indicator | One indicator value, with its live price context. |
| GET | /v1/indicators | Every cached indicator for a symbol, optionally by category. | |
| GET | /v1/indicators/list | The catalogue of indicator keys you can ask for. | |
| GET | /v1/indicator/history | A time series of one indicator. PAYG and up. | |
| GET | /v1/multi | Several indicators across several symbols in one call. | |
| GET | /v1/screener | Symbols filtered by one indicator’s value. | |
| Analytics | GET | /v1/summary | Market-state summary: bias, confidence, scores, key levels. |
| GET | /v1/heatmap | Currency strength, or the correlation matrix. | |
| GET | /v1/spread | Spread statistics over a chosen period. | |
| GET | /v1/spread/compare | The same statistics across a symbol list. | |
| GET | /v1/sessions | Which sessions are open, and their overlaps. | |
| Calendar | GET | /v1/calendar | Economic events with impact, forecast, previous and actual. |
| Account | GET | /v1/monitor/account | Plan, prepaid credit and quota consumption. |
| GET | /v1/monitor/layout | The saved dashboard layout, or null. | |
| PUT | /v1/monitor/layout | The one write route the clients expose. |
A separate repository packages the API for agent runtimes: a Claude Agent Skill that carries the knowledge, a read-only MCP server that carries the typed execution path, and a dependency-free CLI for anything that can run a shell. It installs from a clone — it is not on a package registry.
SKILL.md is the knowledge half: when this API is relevant, which
enum values exist, and how to read a response. It carries no secrets and works
with either calling path. Copy it into a skill folder your client loads.
A Python MCP server exposing the endpoints as typed tools with JSON-schema inputs, auth, retries and clean errors. Deliberately read-only: the one write route is not exposed. Works with any MCP client.
One standard-library Python script, JSON on stdout and meaningful exit codes, for agents and CI runners with no MCP support. 21 subcommands cover the same surface as the MCP tools.
The repo ships end-to-end agent workflows rather than snippets — reading an oversold RSI scan, a currency-strength heatmap, a screener pass and a calendar plus bias lookup.
git clone https://github.com/abuzant/tickatlas-skills.git cd tickatlas-skills # Claude Code — registers the read-only MCP server claude mcp add tickatlas \ --env TICKATLAS_API_KEY=tk_xxxxxxxx \ -- uvx --from ./mcp-server tickatlas-mcp
{
"mcpServers": {
"tickatlas": {
"command": "uvx",
"args": ["--from", "/absolute/path/to/tickatlas-skills/mcp-server", "tickatlas-mcp"],
"env": { "TICKATLAS_API_KEY": "tk_xxxxxxxx" }
}
}
} export TICKATLAS_API_KEY=tk_xxxxxxxx python scripts/tickatlas_cli.py --help # works without a key python scripts/tickatlas_cli.py quote EURUSD python scripts/tickatlas_cli.py summary EURUSD H1 python scripts/tickatlas_cli.py screener RSI_14 --max-val 30 python scripts/tickatlas_cli.py heatmap python scripts/tickatlas_cli.py account
Three things worth knowing while you are choosing whether to depend on a package or call the API directly.
All four packages are REST-only. GET /v1/... is covered; the /ws/v1/quotes socket is out of scope for 0.1.0 and tracked for a later release. Stream over a raw WebSocket client until then — the protocol is four JSON actions.
WebSocket protocol0.1.0 is the only version on any registry. It follows SemVer against the v1 API, so a 0.x pin is the honest pin. Watch the repo rather than expecting a cadence.
Repo and releasesThere is no maintained collection file for either. What does exist is the OpenAPI description behind the API explorer, which both tools can import.
API explorer
Nothing in the API requires a client library. Send X-API-Key to the
REST base URL and read the success + data envelope —
the packages exist to save keystrokes, not to unlock anything. The API reference
carries every parameter and response schema, and the explorer publishes an
OpenAPI description you can generate from.
curl -H "X-API-Key: $TICKATLAS_API_KEY" \
"https://tickatlas.com/v1/indicator?symbol=EURUSD&indicator=RSI_14&timeframe=H1"
# {"success":true,"data":{"symbol":"EURUSD","timeframe":"H1",
# "indicator":"RSI_14","value":58.43,"bid":1.08432,"ask":1.08445,
# "updated_at":1711548000,"server_time":"2024-03-27T14:00:00+00:00"}} What sits either side of the client library, in the order you tend to need it.
What the SDK is wrapping, so you know what it is saving you.
What each typed model is a projection of.
When the answer is an automation tool rather than a client library.
Worked projects that use a client end to end.
All four packages live in one public MIT-licensed monorepo. Open an issue with the package, the version and the failing call — or a pull request, which is faster. Each package ships unit tests that run against recorded payloads plus read-only integration tests behind an opt-in flag.
Reproduce the call with curl and the same key. If the raw call
succeeds, it is the client; if it fails the same way, the error code and the
error reference will name the cause.
What is published, what is in this version, and when calling the API directly is the better answer.
No. The API is plain REST with one header and one response envelope, so any HTTP client works — /docs/quickstart shows the first call in five languages using nothing but each language’s standard facilities. The packages exist to save you writing retry, backoff and error-mapping code, not because the API requires them.
0.1.0, on every registry. It is the only published version, released 2026-06-16, and it follows SemVer against the v1 API. Pin it if you want reproducible builds; a 0.x minor bump may move the surface.
Not in this version. All four packages cover the REST surface only; the WebSocket quote stream is explicitly out of scope for 0.1.0. Use a WebSocket client directly against /ws/v1/quotes — authenticate with one JSON message, then subscribe to symbols.
Explicit constructor argument first, then the TICKATLAS_API_KEY environment variable, then it fails at construction. The base URL resolves the same way through TICKATLAS_BASE_URL, so staging needs no code change. No client logs, prints or persists the key.
The client retries with exponential backoff and jitter, and honours the Retry-After header rather than guessing the delay. If it exhausts its attempts you get the rate-limit exception type, carrying the server-advised delay so you can decide what to do at the application level.
Yes, in a separate repo: a Claude Agent Skill (SKILL.md), a read-only MCP server exposing the endpoints as typed tools, and a zero-dependency Python CLI for any agent that can run a shell. It installs from a git clone, not from a package registry.
Send X-API-Key to the REST base URL with your language’s ordinary HTTP client. The API reference carries every parameter and response schema, and the API explorer publishes an OpenAPI description you can generate a client from.
MIT, all of them, in one public monorepo with a package per language. Issues and pull requests are welcome.
Get a key, export it, and the client handles auth, retries, backoff and error typing from there. What you write next is the part that only you can write.