REST API · v1
API documentation
Submit and retrieve your stock price predictions programmatically. Access is limited to registered accounts with a verified email and an active API key.
Base URL:
Quick start
- Create an account and verify your email.
- Go to Profile → API access and generate an API key. Copy it immediately — it is shown only once.
- Send the key on every request to
/api/v1/*.
curl -X POST "/api/v1/predictions" \
-H "Content-Type: application/json" \
-H "X-API-Key: gtt_live_your_key_here" \
-d '{
"ticker": "TSLA",
"price_target": 450,
"horizon": "12m"
}'
Authentication
All /api/v1/* endpoints require an API key. JWT login tokens used by the website
do not work on v1 routes.
Pass your key using either header:
X-API-Key: gtt_live_abc123...
or
Authorization: Bearer gtt_live_abc123...
- Keys are prefixed with
gtt_live_. - Only the SHA-256 hash is stored server-side; the raw key cannot be recovered.
- Revoke unused keys from your profile. Maximum 5 active keys per account.
- Always use HTTPS in production. Never commit keys to source control.
Endpoints
All v1 responses use JSON with snake_case field names.
/api/v1/horizons
List available prediction time horizons.
Auth: API key
/api/v1/community/:ticker
Community average price target for a ticker. Omit horizon for all periods, or pass one to filter.
Auth: API key
Query: horizon (optional) — 1d, 1w, 1m, 3m, or 12m
/api/v1/predictions
List your predictions, newest first.
Auth: API key
Query: ticker (optional) — filter by symbol, e.g. ?ticker=AAPL
/api/v1/predictions/:id
Get a single prediction by numeric ID. Only returns predictions you own.
Auth: API key
/api/v1/upside-portfolio
Daily top-20 upside portfolio — companies whose community targets imply the highest upside vs current price.
Auth: API key
Query:
horizon(optional) —1d,1w,1m,3m, or12m(default12m)mode(optional) —community(default) orweighted(upside scaled by predictor accuracy)
/api/v1/downside-portfolio
Daily top-20 downside portfolio — companies whose community targets imply the largest drop vs current price.
Auth: API key
Query:
horizon(optional) —1d,1w,1m,3m, or12m(default12m)mode(optional) —community(default) orweighted(downside scaled by predictor accuracy)
/api/v1/predictions
Submit or update a price prediction for a ticker and horizon.
Auth: API key
Body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
ticker | string | yes | US stock symbol, e.g. TSLA |
price_target | number | yes | Target price (must be > 0). Alias: priceTarget |
horizon | string | no | 1d, 1w, 1m, 3m, or 12m (default 12m) |
Responses
Submit prediction — 201 Created or 200 OK (update)
{
"prediction": {
"id": 12345,
"share_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ticker": "TSLA",
"horizon": "12m",
"horizon_label": "12 Months",
"price_target": 450,
"entry_price": 248.5,
"entered_at": "2026-06-28T12:00:00.000Z",
"evaluate_at": "2027-06-28T12:00:00.000Z",
"actual_price": null,
"accuracy_pct": null,
"evaluated_at": null,
"editable": true,
"receipt": {
"shareId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"url": "https://www.getthetape.com/receipt/a1b2c3d4-...",
"imageUrl": "https://www.getthetape.com/api/receipts/a1b2c3d4-.../og.png?v=3"
}
},
"receipt": { "...": "same as prediction.receipt" },
"updated": false
}
Community average (single horizon) — 200 OK
GET /api/v1/community/TSLA?horizon=12m
{
"ticker": "TSLA",
"horizon": "12m",
"horizon_label": "12 Months",
"short_label": "12M",
"avg_price": 312.45,
"submission_count": 87
}
Community average (all horizons) — 200 OK
GET /api/v1/community/TSLA
{
"ticker": "TSLA",
"by_horizon": {
"1d": { "avg_price": 248.1, "submission_count": 12, "label": "1 Day", "short_label": "1D" },
"12m": { "avg_price": 312.45, "submission_count": 87, "label": "12 Months", "short_label": "12M" }
}
}
List predictions — 200 OK
{
"predictions": [ { "...": "prediction object" } ]
}
Horizons — 200 OK
{
"horizons": [
{ "id": "1d", "label": "1 Day", "short_label": "1D", "days": 1 },
{ "id": "1w", "label": "1 Week", "short_label": "1W", "days": 7 },
{ "id": "1m", "label": "1 Month", "short_label": "1M", "days": 30 },
{ "id": "3m", "label": "3 Months", "short_label": "3M", "days": 90 },
{ "id": "12m", "label": "12 Months", "short_label": "12M", "days": 365 }
]
}
Upside portfolio
Refreshed once per day. Each ticker must have at least 25 qualifying predictions for the selected horizon. Only predictors with over 60% directional accuracy are included. API responses include the full top 20 (no guest blur).
Community average — 200 OK
GET /api/v1/upside-portfolio?horizon=12m&mode=community
{
"snapshot_date": "2026-07-22",
"computed_at": "2026-07-22T18:30:00.000Z",
"criteria": {
"horizon": "12m",
"mode": "community",
"min_predictions": 25,
"limit": 20,
"weighting": "Simple average of all community targets."
},
"companies": [
{
"rank": 1,
"ticker": "NVDA",
"prediction_count": 142,
"avg_price_target": 185.5,
"current_price": 142.3,
"upside_pct": 30.4
}
],
"modes": [
{ "id": "community", "label": "Community average" },
{ "id": "weighted", "label": "Accuracy-weighted" }
],
"horizons": [
{ "id": "12m", "label": "12 Months", "short_label": "12M" }
]
}
Accuracy-weighted — 200 OK
Use mode=weighted. Average predicted upside is scaled by community accuracy
(e.g. +10% at 50% accuracy → +5%). Predictors must have over 60% directional accuracy.
GET /api/v1/upside-portfolio?horizon=12m&mode=weighted
The website also exposes GET /api/upside-portfolio without an API key; unauthenticated
requests blur ranks 1–5.
Downside portfolio
Same daily refresh and eligibility rules as the upside portfolio, but ranks companies whose average target is below the current price. Only tickers with negative implied move are included. Move fields are negative percentages (downside).
Community average — 200 OK
GET /api/v1/downside-portfolio?horizon=12m&mode=community
{
"snapshot_date": "2026-07-22",
"computed_at": "2026-07-22T18:30:00.000Z",
"criteria": {
"horizon": "12m",
"mode": "community",
"direction": "downside",
"min_predictions": 25,
"limit": 20,
"weighting": "Simple average of all community targets.",
"move_label": "downside"
},
"companies": [
{
"rank": 1,
"ticker": "XYZ",
"prediction_count": 88,
"avg_price_target": 42.5,
"current_price": 50.0,
"upside_pct": -15.0,
"downside_pct": -15.0
}
]
}
Accuracy-weighted — 200 OK
GET /api/v1/downside-portfolio?horizon=12m&mode=weighted
Public website route: GET /api/downside-portfolio (guest blur on ranks 1–5 without login).
Errors
Errors return JSON with an error message. Some include a code field.
| Status | Code | Meaning |
|---|---|---|
| 401 | API_KEY_REQUIRED | No API key provided |
| 401 | API_KEY_INVALID | Key is invalid or revoked |
| 403 | EMAIL_NOT_VERIFIED | Verify your email before using the API |
| 403 | API_FORBIDDEN | Account is not eligible for API access |
| 400 | — | Invalid request body (missing ticker, bad horizon, etc.) |
| 404 | — | Ticker not found or prediction does not exist |
| 409 | TARGET_LOCKED | Existing prediction cannot be edited (see rules below) |
{
"error": "API key required. Pass X-API-Key header or Authorization: Bearer <your_key>.",
"code": "API_KEY_REQUIRED"
}
Submission rules
- One active prediction per ticker + horizon at a time. After a prediction is evaluated, you may submit a new one for the same ticker and horizon.
- Submitting again while a prediction is still open updates it if it is still editable.
- Same-day edits are allowed until midnight UTC, except for
1dhorizons which lock immediately after submission. - Entry price is captured from delayed market data at submission time.
- Predictions are evaluated automatically when their horizon expires; accuracy contributes to the public leaderboard.
Manage API keys on your profile page.
For website usage, the separate JWT-based routes at /api/targets remain available when logged in.
