# Aapl.se — API-dokumentation

Aapl.se är Sveriges ledande Apple-nyhetssajt sedan 2008. Vi aggregerar ~40 källor
och sammanfattar på svenska med AI. Den här sidan dokumenterar sajtens publika,
skrivskyddade gränssnitt för utvecklare och AI-agenter.

**Viktigt om innehållet:** de svenska sammanfattningarna är Aapl.se:s eget innehåll.
Originalartiklarna tillhör respektive källa — fulltext exponeras aldrig via något
gränssnitt. Citera gärna "enligt {källa}, via Aapl.se" med länk.

Alla svar är UTF-8. Datumfält märkta *ISO* är ISO 8601 (`published_at`).
Om inget annat anges krävs ingen autentisering och endast `GET` stöds.

---

## 1. Anonyma JSON-endpoints (legacy)

Öppna, skrivskyddade och utan autentisering. Endast `apple_relevant`-artiklar
listas. `items`-parametern begränsas till max 100.

### `GET https://aapl.se/entries.json`
De senaste artiklarna (nyast först). Frivillig parameter: `items` (antal, standard 50, max 100).

Svarsform:

```json
{
  "entries": [
    {
      "id": 123,
      "title": "Apple lanserar ny iPhone",
      "url": "https://källa.example/artikel",
      "image": "https://aapl.se/rails/active_storage/...",
      "summary": "Svensk AI-sammanfattning av artikeln.",
      "source": "MacRumors",
      "source_id": 7,
      "posted": "about 3 hours",
      "published_at": "2026-07-04T09:21:13Z"
    }
  ]
}
```

`posted` är en människoläsbar relativ tid (svenska ord) och kan vara `null`.
Parsa alltid `published_at` (*ISO*) i stället — det kan vara `null` för äldre poster.

### `GET https://aapl.se/entries/popular.json`
Samma svarsform, men ordnad på popularitet (flest klick först, därefter nyast).
Parameter: `items` (standard 50, max 100).

### `GET https://aapl.se/entries/:id.json`
En enskild artikel. Samma objektform som ett element i `entries` ovan (utan
`entries`-omslaget). `:id` måste vara numeriskt.

### `GET https://aapl.se/feeds.json`
Aktiva nyhetskällor:

```json
{ "feeds": [ { "id": 7, "title": "MacRumors" } ] }
```

### `GET https://aapl.se/feeds/:id.json`
Artiklarna för en källa, i samma form som `/entries.json`. Parameter: `items` (standard 50, max 100).

### `GET https://aapl.se/tags.json`
Alla taggar:

```json
{ "tags": [ { "id": 4, "name": "iPhone" } ] }
```

### `GET https://aapl.se/tags/:id.json`
Artiklarna för en tagg, i samma form som `/entries.json`. Parameter: `items` (standard 50, max 100).

---

## 2. `/api/v1` (modernt API, Bearer-auth)

Bas: `https://aapl.se/api/v1`. De flesta endpoints är publika; skicka en token bara
för personaliserade vyer (följda källor). Autentisering sker med
`Authorization: Bearer <token>`.

Listsvar har ett gemensamt hölje:

```json
{
  "data": [ /* ... */ ],
  "pagination": { "current_page": 1, "per_page": 20, "total": 240,
                  "last_page": 12, "has_next": true, "has_prev": false,
                  "next_page": 2, "prev_page": null },
  "meta": { "api_version": "v1", "timestamp": "2026-07-04T09:21:13Z", "filters": {} }
}
```

Fel returneras som `{ "error": { "type": "...", "message": "..." }, "meta": { ... } }`
med lämplig HTTP-status (`404`, `400`, `401`, `422`).

Paginering: `?per_page=` (max 100). Språkfilter där det anges: `?lang=sv` eller `?lang=en`.

| Metod & sökväg | Auth | Beskrivning |
|---|---|---|
| `POST /api/v1/auth/login` | – | Logga in med `provider` (`email`, `apple`, `google`); returnerar en token. |
| `POST /api/v1/auth/logout` | Bearer | Roterar och ogiltigförklarar den aktuella token. |
| `DELETE /api/v1/auth/account` | Bearer | Raderar det autentiserade kontot permanent. |
| `GET /api/v1/entries` | valfri | Artiklar (nyast först). `?sort=popular`, `?lang=`. |
| `GET /api/v1/entries/popular` | – | Artiklar ordnade på popularitet. |
| `GET /api/v1/entries/follows` | **Bearer** | Artiklar från användarens följda källor. |
| `GET /api/v1/feeds` | valfri | Aktiva källor (med `entries_count`, `is_following`). |
| `GET /api/v1/feeds/:id` | valfri | En källa i detalj. |
| `GET /api/v1/feeds/:id/entries` | valfri | Artiklar för en källa. |
| `POST /api/v1/feeds/:id/follow` | **Bearer** | Följ en källa (idempotent). |
| `DELETE /api/v1/feeds/:id/follow` | **Bearer** | Sluta följa en källa (idempotent). |
| `GET /api/v1/tags` | – | Taggar med artiklar. |
| `GET /api/v1/tags/:id` | – | En tagg i detalj (`:id` = slug). |
| `GET /api/v1/tags/:id/entries` | – | Artiklar för en tagg. |

Artikelobjekten i `/api/v1` innehåller `id`, `url`, `main_image_url`,
`published_at` (*ISO*), `click_count`, `apple_relevant`, en `feed`, ett
`content`-objekt (`original`/`translated` med `title`, `summary`, `language`)
och `tags`. Även här är `content.*.summary` sammanfattning/utdrag — aldrig full
originaltext.

---

## 3. Markdown för agenter

Token-effektiva markdown-ytor med endast metadata + svensk sammanfattning.
Alla bär `X-Robots-Tag: noindex` och sätter aldrig cookies.

- `https://aapl.se/entries/:id.md` — en artikel som markdown (YAML-frontmatter med
  `title`, `source`, `original_url`, `canonical_url`, `published` (*ISO*),
  `tags`, `language`, följt av rubrik + sammanfattning + länk till originalet).
  Lägg `.md` på valfri artikel-URL, eller skicka `Accept: text/markdown`
  (fungerar när headern inte innehåller `*/*`).
- `https://aapl.se/index.md` — de senaste 50 `apple_relevant`-artiklarna som en
  markdown-lista som länkar till respektive `.md`-version.
- `https://aapl.se/llms.txt` — startpunkt för agenter (llmstxt.org-format) som knyter
  ihop alla ytor ovan.

---

## 4. MCP-server (Model Context Protocol)

`https://aapl.se/mcp` — stateless Streamable HTTP, ingen autentisering. Anslut som
custom connector i Claude (Settings → Connectors) eller i ChatGPT developer mode.
Servern exponerar skrivskyddade verktyg: `latest_news`, `popular_news`,
`search_news` (semantisk sökning), `get_entry`, `list_feeds` och `list_tags`.
Verktygssvaren följer samma innehållssnitt som markdown-ytorna (sammanfattning +
metadata, aldrig originaltext).

---

## 5. Fel & format

- Okända artiklar/sökvägar returnerar HTTP 404 med en **HTML**-body
  (`public/404.html`), inte JSON — kontrollera statuskoden, inte kroppen.
- `.json`-endpoints i avsnitt 1 kräver `.json`-suffix i sökvägen (inte bara en
  `Accept`-header).
- RSS finns på `https://aapl.se/entries.rss` (senaste 50, med taggar och bilder).

---

*Genererad från Aapl.se. Autentisering med query-parameter (`?token=`) är
avsiktligt odokumenterad och stöds inte för nya integrationer.*
