---
name: sctech-news-api
description: "Fetch real-time Bolivia news, market data, and media source metadata from the SC Tech News public API. Use when the user asks about Bolivia news, current events, exchange rates (dolar blue), or needs to analyze Bolivian media coverage."
---

# SC Tech News API

Public API for Bolivia news articles from 12 media sources with bias metadata and market indicators.

**Base URL:** `https://bolivia-news-production.up.railway.app/api/v1`

## Authentication

Endpoints marked (public) require no auth. All others require a Bearer token:

```
Authorization: Bearer {{API_KEY}}
```

Get a key at https://bolivia-news-production.up.railway.app/guides

## MCP server (recommended)

There is an MCP server at `POST /api/v1/mcp`. Connecting it is usually better than
calling the endpoints by hand: the tools are self-describing and the responses come back
structured.

```
claude mcp add --transport http sctech \
  https://bolivia-news-production.up.railway.app/api/v1/mcp \
  --header "Authorization: Bearer {{API_KEY}}"
```

Or in the project's `.mcp.json`:

```json
{"mcpServers":{"sctech":{"type":"http","url":"https://bolivia-news-production.up.railway.app/api/v1/mcp","headers":{"Authorization":"Bearer {{API_KEY}}"}}}}
```

Tools: `buscar_noticias`, `ultimos_titulares`, `leer_articulo`, `listar_fuentes`,
`indicadores_mercado`.

It runs over the same API key and the same rate limits as the REST endpoints below.

## Endpoints

### GET /headlines (public)

Latest headlines without full content. No auth required.

```bash
curl https://bolivia-news-production.up.railway.app/api/v1/headlines?limit=10
```

Response:
```json
{
  "data": [
    {
      "id": 25006,
      "title": "Contraloría pide a Migración controlar salida de exautoridades",
      "source": { "name": "El Deber", "slug": "el-deber", "bias": "center" },
      "category": "Politica",
      "publishedAt": "2026-04-29T23:51:07.000Z"
    }
  ]
}
```

### GET /search (public)

Full-text search over headlines and excerpts, in Spanish.

Scoped to **today** by default. This is deliberate: a news search that sweeps the whole
archive on every keystroke is the cheapest way to exhaust the database. Widen it
explicitly with `scope` when today has nothing.

```bash
curl "https://bolivia-news-production.up.railway.app/api/v1/search?q=comarapa+bloqueo&scope=day&limit=10"
```

**Parameters:**

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `q` | string | — | **Required.** 2–120 chars. Supports `"exact phrase"`, `or`, and `-exclude` |
| `scope` | string | `day` | `day` (today, Bolivia time), `week` (last 7 days), `archive` (everything) |
| `limit` | int | 20 | Max results (max 50) |
| `offset` | int | 0 | Pagination offset (max 200) |

The query is parsed with Postgres `websearch_to_tsquery`, so malformed input never
errors — it just matches nothing.

Response:
```json
{
  "data": [
    {
      "id": 25006,
      "title": "Dan cuarto intermedio en el bloqueo de Comarapa",
      "excerpt": "Los transportistas acordaron...",
      "source": { "name": "El Deber", "slug": "el-deber", "bias": "center" },
      "category": "Politica",
      "publishedAt": "2026-09-10T14:20:00.000Z",
      "url": "https://eldeber.com.bo/...",
      "author": "Redacción",
      "curated": true
    }
  ],
  "meta": {
    "query": "comarapa bloqueo",
    "scope": "day",
    "total": 3,
    "totalIsCapped": false,
    "limit": 10,
    "offset": 0
  }
}
```

**Two things to know:**

- Results carry **no `content` field.** Search returns headlines; fetch the body with
  `GET /articles/:id` for the one you actually want. Returning 20 full article bodies
  per query is megabytes over the wire for data nobody reads.
- `totalIsCapped: true` means counting stopped at 500 — `total` is a floor, not an
  exact figure. An uncapped `count(*)` over the archive is the expensive half of a
  search, and it is not worth paying on a public endpoint.

### GET /articles (auth required)

Paginated articles with full content.

```bash
curl -H "Authorization: Bearer {{API_KEY}}" \
  "https://bolivia-news-production.up.railway.app/api/v1/articles?limit=10&source=el-deber&category=economia"
```

**Parameters:**

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `limit` | int | 20 | Max results (max 50) |
| `offset` | int | 0 | Pagination offset |
| `source` | string | — | Filter by source slug (e.g. `el-deber`, `la-razon`) |
| `category` | string | — | Filter by category: `politica`, `economia`, `deportes`, `tecnologia`, `seguridad`, `sociedad` |
| `since` | ISO date | — | Articles after this date (e.g. `2026-04-28`) |

Response:
```json
{
  "data": [
    {
      "id": 25006,
      "title": "Contraloría pide a Migración...",
      "content": "El texto completo del artículo...",
      "excerpt": "",
      "source": { "name": "El Deber", "slug": "el-deber", "bias": "center" },
      "category": "Politica",
      "publishedAt": "2026-04-29T23:51:07.000Z",
      "url": "https://eldeber.com.bo/...",
      "media": ["https://...image.jpg"],
      "author": "Redacción",
      "curated": false
    }
  ],
  "meta": { "total": 25071, "limit": 10, "offset": 0 }
}
```

### GET /articles/:id (auth required)

Single article by ID.

```bash
curl -H "Authorization: Bearer {{API_KEY}}" \
  https://bolivia-news-production.up.railway.app/api/v1/articles/25006
```

### GET /sources (auth required)

Active media sources with bias and factuality metadata.

```bash
curl -H "Authorization: Bearer {{API_KEY}}" \
  https://bolivia-news-production.up.railway.app/api/v1/sources
```

Response:
```json
{
  "data": [
    {
      "id": 1,
      "name": "El Deber",
      "slug": "el-deber",
      "url": "https://eldeber.com.bo",
      "bias": "center",
      "ownership": "private",
      "factuality": "high",
      "country": "Bolivia",
      "city": "Santa Cruz"
    }
  ]
}
```

### GET /market (public)

Current exchange rates and crypto prices.

```bash
curl https://bolivia-news-production.up.railway.app/api/v1/market
```

Response:
```json
{
  "data": [
    { "symbol": "USDT/BOB", "value": "9.54", "change": "+0.0000", "changePercent": "+0.00%", "isUp": true, "lastTime": "6:00 AM UTC" },
    { "symbol": "BTC/USD", "value": "77,867", "change": "+252.95", "changePercent": "+0.32%", "isUp": true, "lastTime": "2:00 PM UTC" }
  ]
}
```

## Rate Limits

| Tier | Limit | Applies to |
|------|-------|-----------|
| No auth | 10 req/min per IP | `/headlines`, `/market`, `/health` |
| With API key | 60 req/min | All endpoints |

Rate limit headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`

## Usage Tips

- Use `/headlines` for quick overviews (no auth needed)
- Use `?source=` to compare coverage from different media outlets
- The `bias` field (left/center/right) helps analyze media perspective
- The `curated` field indicates if the article was AI-processed (currently all `false` — raw scraped content)
- Articles are scraped every ~2 hours from 11 Bolivian media sources
- Market data updates on request (cached 60s server-side)

## Source Slugs

| Source | Slug | Bias |
|--------|------|------|
| La Razón | `la-razon` | center |
| El Deber | `el-deber` | center |
| Opinión | `opinion` | center |
| ANF | `anf-agencia-de-noticias-fides` | center |
| ABI | `abi-agencia-boliviana-de-informacion` | center |
| Ahora El Pueblo | `ahora-el-pueblo` | left |
| Bolivia TV | `bolivia-tv` | left |
| Erbol | `erbol` | center |
| Página Siete | `pagina-siete` | center |
| Los Tiempos | `los-tiempos` | center |
| Cambio | `cambio` | left |
